# classify_spectra

## PURPOSE

CLASSIFY_SPECTRA M-file for classify_spectra.fig

## SYNOPSIS

function varargout = classify_spectra(varargin)

## DESCRIPTION

     CLASSIFY_SPECTRA M-file for classify_spectra.fig
          CLASSIFY_SPECTRA, by itself, creates a new CLASSIFY_SPECTRA or raises the existing
          singleton*.

          H = CLASSIFY_SPECTRA returns the handle to a new CLASSIFY_SPECTRA or
          the handle to
          the existing singleton*.

          CLASSIFY_SPECTRA('CALLBACK',hObject,eventData,handles,...) calls the local
          function named CALLBACK in CLASSIFY_SPECTRA.M with the given input arguments.

          CLASSIFY_SPECTRA('Property','Value',...) creates a new CLASSIFY_SPECTRA or raises the
          existing singleton*.  Starting from the left, property value pairs are
          applied to the GUI before classify_spectra_OpeningFunction gets called.  An
          unrecognized property name or invalid value makes property application
          stop.  All inputs are passed to classify_spectra_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

## CROSS-REFERENCE INFORMATION

This function calls:

- close VR=CLOSE(VR)
- close VW=CLOSE(VW)
- close VR=CLOSE(VR)
- close VW=CLOSE(VW)
- close VR=CLOSE(VR)
- close VW=CLOSE(VW)
- mtdspecgramc Multi-taper derivative of the time-frequency spectrum - continuous process
- mtspecgramc Multi-taper time-frequency spectrum - continuous process
- auto_classify AUTO_CLASSIFY M-file for auto_classify.fig
- configure_classify CONFIGURE_CLASSIFY M-file for configure_classify.fig

This function is called by:

## SUBFUNCTIONS

- function classify_spectra_OpeningFcn(hObject, eventdata, handles, varargin)
- function varargout = classify_spectra_OutputFcn(hObject, eventdata, handles)
- function DirectoryEditBox_Callback(hObject, eventdata, handles)
- function DirectoryEditBox_CreateFcn(hObject, eventdata, handles)
- function segments=LoadSegmentsFromDirectory(directory)
- function handles=Load_InitialSegments(hObject,handles)
- function handles = cindex2imagelist(handles)
- function mapindex = sortindexbypop(handles)
- function mapindex = sortindexbylength(handles)
- function class_string = newclassname(handles)
- function cindex = returnclassindex(handles,classname)
- function handles = add_new_class(handles,segment)
- function handles=ConfigureClassSegment(handles)
- function handles = blankaxes(handles)
- function ClassifyButton_Callback(hObject, eventdata, handles)
- function NewClassButton_Callback(hObject, eventdata, handles)
- function RemoveClassButton_Callback(hObject, eventdata, handles)
- function TypifyClassButton_Callback(hObject, eventdata, handles)
- function segment=precompute_spectra(handles, segment)
- function handles = precompute_AllSpectra(handles)
- function [S t f]=compute_spectra(data,tapers,Fs,fpass,movingwin)
- function handles=get_and_plot(handles, segment)
- function PlotModeCallBack(src,eventdata)
- function handles=ConfigureSpecPlot(handles)
- function NextSpectraButton_Callback(hObject, eventdata, handles)
- function PreviousSpectraButton_Callback(hObject, eventdata, handles)
- function PrecomputeButton_Callback(hObject, eventdata, handles)
- function PlaySegmentButton_Callback(hObject, eventdata, handles)
- function CurrentFilenameEdit_Callback(hObject, eventdata, handles)
- function CurrentFilenameEdit_CreateFcn(hObject, eventdata, handles)
- function newwidth = SmallAxes_width(handles)
- function iconS = iconify_spec(S,height)
- function destination = copy_into(destination,source,r,c)
- function positions = position_images(height,width,images_dim,xspacer,yspacer)
- function image_dim = get_image_sizes(images)
- function image_matrix = place_images_into(image_matrix, image_list, position_list)
- function IconList=get_SpecIcons(handles)
- function handles = plot_classified_axes(handles, image_list, position_list)
- function handles = reposition_images(handles, image_list)
- function nrow = which_row(positions,index)
- function cpositions = get_curr_position(handles)
- function cposition = next_row_start(positions,cposition)
- function cposition = next_row_end(positions,cposition)
- function handles = row_forward(handles)
- function cposition = previous_row_start(positions,cposition)
- function cposition = previous_row_end(positions,cposition)
- function nrows = number_of_rows(handles)
- function handles = row_backward(handles)
- function handles = BrowseDirectory(handles)
- function NextRowButton_Callback(hObject, eventdata, handles)
- function PreviousRowButton_Callback(hObject, eventdata, handles)
- function LoadDirectoryButton_Callback(hObject, eventdata, handles)
- function im_index = coordinate2index(handles,xpos,ypos)
- function setnavigationbuttons(handles)
- function setrowbuttons(handles)
- function DummyClassifyAxesClickCallBack(src,eventdata,handles)
- function ClassifyAxesClickCallBack(src,eventdata)
- function handles = configureclassview(handles,submode)
- function handles = SetModePopupMenu(handles,viewstring)
- function ModePopupMenu_Callback(hObject, eventdata, handles)
- function ModePopupMenu_CreateFcn(hObject, eventdata, handles)
- function set_status(handles, statusstring)
- function handles = configureclassmembers(handles,classname)
- function indexfilter = select_class(handles,segments,classname)
- function cindex = get_class_index(handles,classname);
- function value = mapind(index)
- function write_syllable_database(handles)
- function data = read_syllable_database(handles)
- function handles = merge_syllable_database(handles,data)
- function SaveButton_Callback(hObject, eventdata, handles)
- function SliderClassified_Callback(hObject, eventdata, handles)
- function SliderClassified_CreateFcn(hObject, eventdata, handles)
- function SortPopupMenu_Callback(hObject, eventdata, handles)
- function SortPopupMenu_CreateFcn(hObject, eventdata, handles)
- function segments = rename_segments(segments,oldname,newname)
- function cln = doesclassexist(classname,classes)
- function RenameClassButton_Callback(hObject, eventdata, handles)
- function spectras = subsamplespectra(spectra,lowerfreq,upperfreq,freqrange)
- function handles = generate_subsamples_icons(handles)
- function handles = ZoomSpectra(handles,status)
- function ZoomButton_Callback(hObject, eventdata, handles)
- function [meanl sdl] = stat_lengths(handles)
- function handles = quick_mode_exit(handles)
- function QuickModeButton_Callback(hObject, eventdata, handles)
- function handles=jump_to_unclassified(handles)
- function SkipButton_Callback(hObject, eventdata, handles)
- function UndoButton_Callback(hObject, eventdata, handles)
- function NewQuickButton_Callback(hObject, eventdata, handles)
- function CompareToggleButton_Callback(hObject, eventdata, handles)
- function handles = recompute_classifiedaxes(handles)
- function reposy(guielement,deltay)
- function reposelementsy(handles,deltay)
- function ResizeFcn(h, eventdata, handles, varargin)
- function truth = truthrange(range)
- function ConfigureButton_Callback(hObject, eventdata, handles)
- function status = save_configuration(handles,filename)
- function handles = load_configuration(handles,filename)
- function NextClassButton_Callback(hObject, eventdata, handles)
- function handles = features_segments(handles)
- function coefs = cepsfromspectra(specfilename,ncepestral)
- function classifymatrix = generate_classify_mat(handles)
- function handles = generate_classes_auto(handles,classification)
- function AutoClassifyButton_Callback(hObject, eventdata, handles)
- function FileMenu_Callback(hObject, eventdata, handles)
- function SaveItem_Callback(hObject, eventdata, handles)
- function LoadItem_Callback(hObject, eventdata, handles)
- function HelpMenu_Callback(hObject, eventdata, handles)
- function HelpItem_Callback(hObject, eventdata, handles)
- function AboutItem_Callback(hObject, eventdata, handles)
- function ConfigureItem_Callback(hObject, eventdata, handles)
- function coefs = cepcoefs(data,p)
- function generate_output(handles,absolutetime,filename);
- function ExportDataItem_Callback(hObject, eventdata, handles)
- function CleanDirectoryItem_Callback(hObject, eventdata, handles)

## SOURCE CODE

    0001 function varargout = classify_spectra(varargin)
    0002 % CLASSIFY_SPECTRA M-file for classify_spectra.fig
    0003 %      CLASSIFY_SPECTRA, by itself, creates a new CLASSIFY_SPECTRA or raises the existing
    0004 %      singleton*.
    0005 %
    0006 %      H = CLASSIFY_SPECTRA returns the handle to a new CLASSIFY_SPECTRA or
    0007 %      the handle to
    0008 %      the existing singleton*.
    0009 %
    0010 %      CLASSIFY_SPECTRA('CALLBACK',hObject,eventData,handles,...) calls the local
    0011 %      function named CALLBACK in CLASSIFY_SPECTRA.M with the given input arguments.
    0012 %
    0013 %      CLASSIFY_SPECTRA('Property','Value',...) creates a new CLASSIFY_SPECTRA or raises the
    0014 %      existing singleton*.  Starting from the left, property value pairs are
    0015 %      applied to the GUI before classify_spectra_OpeningFunction gets called.  An
    0016 %      unrecognized property name or invalid value makes property application
    0017 %      stop.  All inputs are passed to classify_spectra_OpeningFcn via varargin.
    0018 %
    0019 %      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
    0020 %      instance to run (singleton)".
    0021 %
    0022 % See also: GUIDE, GUIDATA, GUIHANDLES
    0023
    0024 % Edit the above text to modify the response to help classify_spectra
    0025
    0026 % Last Modified by GUIDE v2.5 26-Jun-2006 23:19:22
    0027
    0028 % Begin initialization code - DO NOT EDIT
    0029 gui_Singleton = 1;
    0030 gui_State = struct('gui_Name',       mfilename, ...
    0031                    'gui_Singleton',  gui_Singleton, ...
    0032                    'gui_OpeningFcn', @classify_spectra_OpeningFcn, ...
    0033                    'gui_OutputFcn',  @classify_spectra_OutputFcn, ...
    0034                    'gui_LayoutFcn',  [] , ...
    0035                    'gui_Callback',   []);
    0036 if nargin & isstr(varargin{1})
    0037     gui_State.gui_Callback = str2func(varargin{1});
    0038 end
    0039
    0040 if nargout
    0041     [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    0042 else
    0043     gui_mainfcn(gui_State, varargin{:});
    0044 end
    0045 % End initialization code - DO NOT EDIT
    0046
    0047 % --- Executes just before classify_spectra is made visible.
    0048 function classify_spectra_OpeningFcn(hObject, eventdata, handles, varargin)
    0049 % This function has no output args, see OutputFcn.
    0050 % hObject    handle to figure
    0051 % eventdata  reserved - to be defined in a future version of MATLAB
    0052 % handles    structure with handles and user data (see GUIDATA)
    0053 % varargin   command line arguments to classify_spectra (see VARARGIN)
    0054
    0055 % Choose default command line output for classify_spectra
    0056 handles.output = hObject;
    0057
    0058 % Set defaults
    0059 handles.recompute = logical(1); % Whether to recompute a spectra
    0060 handles.cwavfile = ''; % The current wave file
    0061
    0062 handles.directory = pwd;
    0063
    0064 handles.Fs = 44100; % Frequency of audio sampling per second
    0065 handles.movingwin=[0.01 0.002]; % Size of the moving window in seconds; the first number is the window size and the second is the step size
    0066 handles.tapers=[3 5];
    0067 handles.pad=1;
    0068 handles.fpass=[0 20000]; % Range of frequency sampling
    0069
    0070 handles.nsegments = 0; % total number of segments
    0071 handles.NextIndex = 1; % the index for segments
    0072 handles.maxseglength = 0; % set in seconds
    0073
    0074 % ClassifyAxes handles
    0075
    0076 handles.classified_height = 560 ; % the height of the image in the classified axes
    0077 handles.classified_width = 450;  % the width of the image in the classified axes
    0078
    0079 %
    0080
    0081 handles.plotmode = 'spectra'; % The main spectra plot mode can also be
    0082                               % see plot modes
    0083
    0084 handles.plotmodes = {'spectra' 'waveform' 'spectra_dt' 'spectra_df' };
    0085
    0086 handles.plotmodevalue = 1;
    0087
    0088 % set up a density measurement which will allow scaling
    0089
    0090 classaxpos = get(handles.ClassifiedAxes,'Position');
    0091 handles.classified_height_density =  handles.classified_height / classaxpos(4);
    0092 handles.classified_width_density =   handles.classified_width / classaxpos(3);
    0093
    0094 handles.ispecheight = 100; % fixed height of the iconized spectogram
    0095 handles.ismaxwidth = SmallAxes_width(handles);
    0096 handles.specpad = 0.02; % pad in image sizes
    0097
    0098 handles.xspacer = 5; % fixed space between the images in the horizontal direction
    0099 handles.yspacer = 10; % fixed space between the row of the images
    0100
    0101 handles.xpsacer_density = handles.xspacer / classaxpos(3);
    0102 handles.ypsacer_density = handles.yspacer / classaxpos(4);
    0103
    0104 handles.image_list = {}; % holds an array of the specicons
    0105 handles.positions = [];  % holds the position of images on infinitely long canvas
    0106 handles.images_dim = []; % holds the size of the images
    0107
    0108 handles.mapindex = []; % holds the position number for the segment
    0109
    0110 handles.nimages = 0; % total number of images or spectra
    0111 handles.number_rows = floor(handles.classified_height/(handles.yspacer + handles.ispecheight)); % the number of rows allowed on a page
    0112
    0113 handles.cnrows = 0; % current number of rows
    0114
    0115 handles.startpage = 1; % an index for the first image on the page
    0116 handles.endpage = 1; % an index for the last image on the page
    0117
    0118 handles.startx = 1; % for the classified axes holds the start position for the image
    0119 handles.endx = handles.classified_width; % for the classified axes holds the end position for the image
    0120
    0121 handles.mode = 'browse';  % A string representing the current major mode which is either
    0122                           % 'browse','classify','class-view','class-members'
    0123
    0124 handles.submode = 'select'; %A string representing the minor mode which is either
    0125                             % 'select','select-class','remove-class', 'compare',
    0126                             % 'typify'
    0127
    0128 handles.quickmode = logical(0); % Quick mode allows quick classification with minimum
    0129                                 % work for the user. By default this is set
    0130                                 % off
    0131
    0132 handles.lastsegment = 1; % The last segment classified
    0133
    0134
    0135 handles.sortclass = 'length'; % Tells how classes are to be ordered in the ClassifiedAxes
    0136                                 % 'original' is the order the classes were created or loaded from
    0137                                 % 'popularity' sort the classes with most popular first
    0138                                 % 'length' sort the classes by longest
    0139                                 %  class first
    0140
    0141 set(handles.SortPopupMenu,'Value',3);
    0142
    0143 handles.lastclass = 0;
    0144
    0145 handles.lowerfreq = 0;  % Lower frequency for zooming
    0146 handles.upperfreq = 7500; % Upper frequency for zooming
    0147 handles.rezoom = logical(1);
    0148
    0149 handles.IconListf = {};
    0150
    0151 handles.baseclassname = 'mockingbird'; % This string should be set by the user
    0152                                        % used as the base class name
    0153 handles.nclasses = 0; % total number of syllable classes
    0154 handles.classes = []; % structure for holding class information
    0155 handles.current_class = 0; % used by compare to go through classes
    0156
    0157 handles.configschanged = logical(0); % indicates whether the configs for spectra has changed
    0158
    0159 handles.precomputed = logical(0);
    0160
    0161 handles.configfile = 'class_spec.conf';
    0162
    0163 handles.originalsize = [0 0 170 44]; % original position of the form
    0164 handles.originalaxessize = [80.5 6.375 86.167 34.438];
    0165 handles.blank = logical(1); % indicate that the ClassifiedAxes is blank
    0166 handles.prevsize = handles.originalsize;
    0167
    0168 handles.fixed = logical(1); % Whether to use fixed scaling when resizing the form
    0169 % initially set to true so not to call the repositioning algorithm when the
    0170 % form is blank
    0171 handles.nfeatures = 10;
    0172 handles.ncepestral = 10; % Number of cepestral coefficients to include
    0173
    0174 set(gcf, 'ResizeFcn', {@ResizeFcn});
    0175 %classify_spectra('ResizeFcn',gcbo,[],guidata(gcbo))
    0176 % Update handles structure
    0177 guidata(hObject, handles);
    0178
    0179 % UIWAIT makes classify_spectra wait for user response (see UIRESUME)
    0180 % uiwait(handles.figure1);
    0181
    0182 % --- Outputs from this function are returned to the command line.
    0183 function varargout = classify_spectra_OutputFcn(hObject, eventdata, handles)
    0184 % varargout  cell array for returning output args (see VARARGOUT);
    0185 % hObject    handle to figure
    0186 % eventdata  reserved - to be defined in a future version of MATLAB
    0187 % handles    structure with handles and user data (see GUIDATA)
    0188
    0189 % Get default command line output from handles structure
    0190 varargout{1} = handles.output;
    0191
    0192 function DirectoryEditBox_Callback(hObject, eventdata, handles)
    0193 handles.directory = get(hObject,'String');
    0194
    0195 function DirectoryEditBox_CreateFcn(hObject, eventdata, handles)
    0196 set(hObject,'string',pwd);
    0197 guidata(gcbo,handles);
    0198 if ispc
    0199     set(hObject,'BackgroundColor','white');
    0200 else
    0201     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
    0202 end
    0203
    0204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0205 % Functions for loading segments  %
    0206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0207
    0208 function segments=LoadSegmentsFromDirectory(directory)
    0209 segfilelist = dir( [directory '\*' '.seg.txt'] );
    0210 %segfilelist;
    0211 nsegfile = length(segfilelist);
    0212 segments = [];
    0213 n = 1;
    0214 while n <= nsegfile
    0215     segfilename = segfilelist(n).name;
    0216     fid=fopen( segfilename, 'rt' );
    0217     if fid ~= -1 % if there is a seg file
    0218         scanned=fscanf( fid, '%g %g',[2 inf] );
    0219         fclose(fid);
    0220         %fprintf( 'File %d of %d has %d segments: %s\n', n, nsegfile, size(scanned,2),segfilename );
    0221         wavfile = segfilename(1:(length(segfilename)-8)); % can this be made more general
    0222         i = 1;
    0223         while i <= size(scanned, 2) % Load the start and stop of segments
    0224             segment.wavfile = wavfile;
    0225             segment.class = ''; % Loaded segments start out unclassified
    0226             segment.features = [];
    0227             segment.start = scanned(1,i);
    0228             segment.end = scanned(2,i);
    0229             segment.specfilename = [segment.wavfile '.' num2str(segment.start) '-' num2str(segment.end) '.spec'];
    0230             segments = [ segments segment];
    0231             i = i + 1;
    0232         end
    0233     end
    0234     n = n + 1;
    0235 end
    0236
    0237 function handles=Load_InitialSegments(hObject,handles)
    0238   %handles.directory = pwd;
    0239   handles.segments = LoadSegmentsFromDirectory(handles.directory);
    0240   handles.nsegments = length(handles.segments);
    0241   guidata(hObject, handles);
    0242
    0243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0244 % Functions for handling syllable classes  %
    0245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0246
    0247 function handles = cindex2imagelist(handles)
    0248 % Takes a cindex and generates a a list of images
    0249 handles.image_list = {};
    0250 %load('-mat','specicons');
    0251 for i = 1:length(handles.mapindex)
    0252     handles.image_list{i} = handles.classes( handles.mapindex(i) ).iconS;
    0253 end
    0254
    0255 function mapindex = sortindexbypop(handles)
    0256 % Takes a cindex and sorts by the class popularity
    0257 nindexes = length(handles.mapindex);
    0258 mapindex = [];
    0259 for i = 1:nindexes
    0260     mapindex(i,1:2) = [handles.mapindex(i) handles.classes(handles.mapindex(i)).nmembers];
    0261 end
    0262 mapindex = sortrows(mapindex, 2);
    0263 mapindex = flipud(mapindex(:,1));
    0264
    0265 function mapindex = sortindexbylength(handles)
    0266 % Takes a cindex and sorts by the class popularity
    0267 nindexes = length(handles.mapindex);
    0268 mapindex = [];
    0269 for i = 1:nindexes
    0270     mapindex(i,1:2) = [handles.mapindex(i) handles.classes(handles.mapindex(i)).length];
    0271 end
    0272 mapindex = sortrows(mapindex, 2);
    0273 mapindex = flipud(mapindex(:,1));
    0274
    0275 function class_string = newclassname(handles)
    0276 % Generates a new name for the class string using the baseclassname
    0277 % variable. Classes are numbered sequentially from the class with the largest number.
    0278
    0279 nbaseclass = length(handles.baseclassname);
    0280 classnum = 0;
    0281 for i = 1:handles.nclasses % make sure the largest class number is gotten
    0282     classname = handles.classes(i).name;
    0283     curr_classnum = str2num(classname(nbaseclass + 1:length(classname)));
    0284     if curr_classnum > classnum
    0285         classnum = curr_classnum;
    0286     end
    0287 end
    0288 class_string = strcat(handles.baseclassname,num2str(classnum + 1));
    0289 ;
    0290
    0291 function cindex = returnclassindex(handles,classname)
    0292 % Return the index to the class
    0293     cindex = 0;
    0294     i = 1;
    0295     while (i <= handles.nclasses) && not(strcmp(classname,handles.classes(i).name))
    0296         i = i + 1;
    0297     end
    0298     cindex = i;
    0299 ;
    0300
    0301 function handles = add_new_class(handles,segment)
    0302 % Segment is the class that will be used to typify the class
    0303 handles.nclasses = length(handles.classes);
    0304 class.name = newclassname(handles);
    0305 class.nmembers = 1; % the number of segments which are members of this class
    0306 class.specfilename = segment.specfilename; % specfilename will be used as a unique identifier
    0307 class.index = handles.NextIndex;
    0308 %load('-mat',class.specfilename);
    0309 class.iconS = handles.IconList{handles.NextIndex}; % this is the icon which typifies the class
    0310 class.length = segment.end - segment.start; % used to hold the lengt of the length
    0311
    0312 handles.classes = [handles.classes class];
    0313 handles.nclasses = handles.nclasses + 1;
    0314 %guidata(gcbo,handles);
    0315 ;
    0316
    0317 function handles=ConfigureClassSegment(handles)
    0318 % Handles the gui configuration of the class information when navigating
    0319 segment = handles.segments(handles.NextIndex);
    0320 if strcmp(segment.class,'') % Unclassified segment
    0321     set(handles.ClassifyButton,'String','Classify');
    0322     set(handles.ClassifyButton,'Enable','on');
    0323 else % Classified segment
    0324     set(handles.ClassifyButton,'String','Declassify');
    0325     set(handles.ClassifyButton,'Enable','on');
    0326 end
    0327 %guidata(gcbo,handles);
    0328
    0329 function handles = blankaxes(handles)
    0330     set(handles.NextRowButton,'Enable','off');
    0331     set(handles.PreviousRowButton,'Enable','off');
    0332     axes(handles.ClassifiedAxes);
    0333     handles.hiclass = image(uint8(zeros(handles.classified_height,handles.classified_width)));
    0334     set(handles.ClassifiedAxes,'Xtick',[]);
    0335     set(handles.ClassifiedAxes,'Ytick',[]);
    0336     handles.blank = logical(1);
    0337
    0338 % --- Executes on button press in ClassifyButton.
    0339 function ClassifyButton_Callback(hObject, eventdata, handles)
    0340 % hObject    handle to ClassifyButton (see GCBO)
    0341 % eventdata  reserved - to be defined in a future version of MATLAB
    0342 % handles    structure with handles and user data (see GUIDATA)
    0343
    0344 status = get(handles.ClassifyButton,'String');
    0345 set(handles.TypifyClassButton,'Visible', 'off');
    0346 set(handles.RemoveClassButton, 'Visible', 'off');
    0347 set(handles.NextClassButton,'Visible','off');
    0348 % set(handles.CompareToggleButton,'Visible','off');
    0349 set(handles.RenameClassButton,'Visible','off');
    0350 handles.startx = 1; % if you have been scrolling reset to defaults
    0351 handles.endx = handles.classified_width;
    0352 set(handles.SliderClassified,'Value',0);
    0353
    0354 if strcmp(status,'Classify')
    0355     set_status(handles,'');
    0356     set(handles.ModePopupMenu,'Enable','off');
    0357     set(handles.NextSpectraButton,'Enable','off');
    0358     set(handles.PreviousSpectraButton,'Enable','off');
    0359     set(handles.ClassifyButton,'Enable','off');
    0360     set(handles.CompareToggleButton,'Enable','off');
    0361     set(handles.QuickModeButton,'Enable','off');
    0362     set(handles.AutoClassifyButton,'Enable','off');
    0363     set(handles.NewClassButton,'Visible','on');
    0364     if handles.nclasses > 0 % Make sure there is at least one class
    0365         if strcmp(handles.mode,'comparison') % if you are in comparison mode
    0366             set(handles.NewClassButton,'Visible','off');
    0367             handles.segments(handles.NextIndex).class = handles.classes(handles.lastclass).name;
    0368             set(handles.ModePopupMenu,'Enable','on');
    0369             set(handles.ClassifyButton,'String','Declassify');
    0370             set(handles.ClassifyButton,'Enable','on');
    0371             set(handles.CompareToggleButton,'value',0);
    0372             set(handles.CompareToggleButton,'Enable','on');
    0373             handles = configureclassview(handles,'select-class');
    0374             set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    0375             set(handles.RemoveClassButton,'Enable','on');
    0376             set(handles.RemoveClassButton,'Visible','on');
    0377             set(handles.QuickModeButton,'Enable','on');
    0378             set(handles.AutoClassifyButton,'Enable','on');
    0379             setnavigationbuttons(handles);
    0380         else % regular mode
    0381             set(handles.SortText,'Visible','on');
    0382             set(handles.SortPopupMenu,'Visible','on');
    0383             handles = configureclassview(handles,'select-class');
    0384             set_status(handles, ['Select a class']);
    0385         end
    0386     else % draw a blank image
    0387         handles = blankaxes(handles);
    0388         handles.mode = 'class-view';
    0389         handles.submode = 'select-class';
    0390         set(handles.hiclass,'ButtonDownFcn',{@DummyClassifyAxesClickCallBack,handles});
    0391     end
    0392     % configure the remaining gui
    0393     handles = SetModePopupMenu(handles,'class view');
    0394 elseif strcmp(status,'Declassify')
    0395     cindex = returnclassindex(handles,handles.segments(handles.NextIndex).class);
    0396     if handles.classes(cindex).nmembers == 1 % Only one member left of that class
    0397         if length(handles.classes) == 1 % Only one class remaining
    0398             axes(handles.ClassifiedAxes);
    0399             handles.classes = [];
    0400             handles.nclasses = 0;
    0401             handles = blankaxes(handles);
    0402         else % remove the class
    0403             handles.classes = [handles.classes(1:cindex-1) handles.classes(cindex + 1:length(handles.classes))];
    0404             handles.nclasses = handles.nclasses - 1;
    0405         end
    0406     else
    0407         if strcmp(handles.classes(cindex).specfilename,handles.segments(handles.NextIndex).specfilename)
    0408             i = 1; %Test if the class you are removing the type class
    0409             segs = [ handles.segments(1:(handles.NextIndex - 1)) handles.segments((handles.NextIndex + 1) : handles.nclasses)];
    0410             while (i <= length(segs)) && strcmp(segs(i).class,handles.classes(cindex).name)
    0411                 i = i + 1;
    0412             end
    0413             handles.classes(cindex).specfilename = handles.segments(i).specfilename;
    0414             handles.classes(cindex).length = handles.segments(i).end - handles.segments(i).start;
    0415             handles.iconS = handles.IconList{i};
    0416         end
    0417         handles.classes(cindex).nmembers = handles.classes(cindex).nmembers - 1;
    0418     end
    0419     handles.segments(handles.NextIndex).class = ''; % Remove class information
    0420     if handles.nclasses >= 1 % Redraw axes
    0421         if strcmp(handles.mode,'class-view')
    0422             handles = configureclassview(handles,'select');
    0423             set_status(handles,['Viewing all ' num2str(handles.nclasses)  ' classes']);
    0424         elseif strcmp(handles.mode,'class-members')
    0425             handles = configureclassmembers(handles,handles.classes(cindex).name);
    0426             set_status(handles,['Viewing ' num2str(handles.classes(cindex).nmembers) ' members of ' num2str(handles.classes(cindex).name)]);
    0427         elseif strcmp(handles.mode,'browse')
    0428             ; % do nothing
    0429         end
    0430     end
    0431     set(handles.ClassifyButton,'String','Classify');
    0432
    0433     setnavigationbuttons(handles);
    0434 end
    0435 guidata(gcbo,handles);
    0436
    0437
    0438 % --- Executes on button press in NewClassButton.
    0439 function NewClassButton_Callback(hObject, eventdata, handles)
    0440 % hObject    handle to NewClassButton (see GCBO)
    0441 % eventdata  reserved - to be defined in a future version of MATLAB
    0442 % handles    structure with handles and user data (see GUIDATA)
    0443
    0444 handles.startx = 1; % if you have been scrolling reset to defaults
    0445 handles.endx = handles.classified_width;
    0446 set(handles.SliderClassified,'Value',0);
    0447
    0448 handles = add_new_class(handles,handles.segments(handles.NextIndex));
    0449 handles.segments(handles.NextIndex).class = handles.classes(handles.nclasses).name;
    0450
    0451 set(handles.SortText,'Visible','off');
    0452 set(handles.SortPopupMenu,'Visible','off');
    0453 set(handles.ClassifyButton,'Enable','on');
    0454 set(handles.ClassifyButton,'String','Declassify');
    0455 set(handles.NewClassButton,'Visible','off');
    0456 set(handles.ModePopupMenu,'Enable','on');
    0457 set(handles.NextSpectraButton,'Enable','on');
    0458 set(handles.CompareToggleButton,'Enable','on');
    0459 set(handles.QuickModeButton,'Enable','on');
    0460 set(handles.AutoClassifyButton,'Enable','on');
    0461 set(handles.PreviousSpectraButton,'Enable','on');
    0462 handles = configureclassview(handles,'xxx');
    0463 setnavigationbuttons(handles);
    0464 set_status(handles,'');
    0465 handles = SetModePopupMenu(handles,'class view');
    0466 guidata(gcbo,handles);
    0467 ;
    0468
    0469 % --- Executes on button press in RemoveClassButton.
    0470 function RemoveClassButton_Callback(hObject, eventdata, handles)
    0471 % hObject    handle to RemoveClassButton (see GCBO)
    0472 % eventdata  reserved - to be defined in a future version of MATLAB
    0473 % handles    structure with handles and user data (see GUIDATA)
    0474
    0475 %set(handles.TypifyClassButton,'Enable','on');
    0476 set(handles.RemoveClassButton,'Enable','off');
    0477 handles.mode = 'class-view';
    0478 handles.submode = 'remove-class';
    0479 set_status(handles,'Select a class to remove');
    0480 guidata(gcbo,handles);
    0481
    0482
    0483 % --- Executes on button press in TypifyClassButton.
    0484 function TypifyClassButton_Callback(hObject, eventdata, handles)
    0485 % hObject    handle to TypifyClassButton (see GCBO)
    0486 % eventdata  reserved - to be defined in a future version of MATLAB
    0487 % handles    structure with handles and user data (see GUIDATA)
    0488
    0489 set(handles.TypifyClassButton,'Enable','off');
    0490 %set(handles.RemoveClassButton,'Enable','on');
    0491 handles.mode = 'class-members';
    0492 handles.submode = 'typify';
    0493 set_status(handles,'Select an icon to change the type');
    0494 guidata(gcbo,handles);
    0495
    0496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0497 % Functions for computing the spectra    %
    0498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0499
    0500 function segment=precompute_spectra(handles, segment)
    0501 % This function will do the precomputing of the spectragram
    0502 spec_ipad = round(handles.specpad * handles.Fs);
    0503 spec_istart = round(segment.start * handles.Fs);
    0504 spec_iend = round(segment.end * handles.Fs);
    0505
    0506 % This is to catch an over and under run errors in the wav file because of the padding
    0507 try
    0508     [data] = wavread(segment.wavfile, [spec_istart - spec_ipad, spec_iend + spec_ipad]);
    0509 catch
    0510     errmsg = lasterr;
    0511     if strfind(errmsg, 'Sample limits out of range')
    0512         if (segment.start - handles.specpad) < 0 % Make sure the starting point is not negative
    0513             [data] = wavread(segment.wavfile, [1 spec_iend + spec_ipad]);
    0514         else % over run of the buffer
    0515             [data] = wavread(segment.wavfile);
    0516             [data] = data((spec_istart - spec_ipad):length(data));
    0517         end
    0518     end
    0519 end
    0520
    0521 [Sfull tfull f] = compute_spectra(data,handles.tapers,handles.Fs,handles.fpass,handles.movingwin); % precompute the portion
    0522
    0523 wavlength = length(data);
    0524 Ssize = size(Sfull);
    0525
    0526 Slength = Ssize(2);
    0527 RatioWS = Slength / (wavlength / handles.Fs); % this allows us to index by time through spec file
    0528
    0529 Sstart = round(RatioWS * segment.start);
    0530 Send = round(RatioWS * segment.end);
    0531 Spad = round(RatioWS * handles.specpad);
    0532
    0533 Spre = Sfull(:,1:Spad);
    0534 S = Sfull(:,Spad+1:Spad + Send-Sstart);
    0535 Spost = Sfull(:,Spad + (Send-Sstart)+1:Slength);
    0536 t=[segment.start, segment.end];
    0537
    0538 iconS = iconify_spec(S,handles.ispecheight);
    0539
    0540 save(segment.specfilename,'S','t','f','Spre','Spost','RatioWS','tfull','iconS','-mat');
    0541
    0542 fprintf('Saving %s file\n',segment.specfilename);
    0543
    0544 function handles = precompute_AllSpectra(handles)
    0545 % This function precomputes all the spectra in a directory
    0546 hw = waitbar(0,'Precomputing spectra. . .');
    0547 if handles.nsegments >= 1
    0548     for i = 1:handles.nsegments
    0549         precompute_spectra(handles,handles.segments(i));
    0550         waitbar(i/handles.nsegments);
    0551     end
    0552 end
    0553 close(hw);
    0554 handles.IconList = get_SpecIcons(handles);
    0555 ;
    0556 function [S t f]=compute_spectra(data,tapers,Fs,fpass,movingwin)
    0557     data = data / std(data); % normalize the variance of the spectra
    0558     params.tapers=tapers; params.Fs=Fs; params.fpass=fpass;
    0559     [S t f] = mtspecgramc( diff(data), movingwin, params );
    0560     S = log(S)';
    0561
    0562
    0563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0564 % Functions for plotting the spectragram   %
    0565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0566
    0567 function handles=get_and_plot(handles, segment)
    0568 load('-mat',segment.specfilename);
    0569 axes(handles.ToClassifyAxes);
    0570 % RatioWS
    0571
    0572 cmap = jet(256);
    0573
    0574 if strcmp(handles.plotmode,'spectra')
    0575     SFull = cat(2,Spre,S,Spost);
    0576 elseif strcmp(handles.plotmode,'spectra_dt') || strcmp(handles.plotmode,'spectra_df') || strcmp(handles.plotmode,'waveform')
    0577     wav_ipad = round(handles.specpad * handles.Fs);
    0578     wav_istart = round(segment.start * handles.Fs);
    0579     wav_iend = round(segment.end * handles.Fs);
    0580
    0581     % This is to catch an over and under run errors in the wav file because of the padding
    0582     try
    0583         [data] = wavread(segment.wavfile, [wav_istart - wav_ipad, wav_iend + wav_ipad]);
    0584     catch
    0585         errmsg = lasterr;
    0586         if strfind(errmsg, 'Sample limits out of range')
    0587             if (segment.start - handles.specpad) < 0 % Make sure the starting point is not negative
    0588                 [data] = wavread(segment.wavfile, [1 wav_iend + wav_ipad]);
    0589             else % over run of the buffer
    0590                 [data] = wavread(segment.wavfile);
    0591                 [data] = data((wav_istart - wav_ipad):length(data));
    0592             end
    0593         end
    0594     end
    0595
    0596     data = data / std(data);
    0597
    0598     params.Fs=handles.Fs;
    0599     params.tapers = handles.tapers;
    0600     params.fpass=handles.fpass;
    0601     params.pad = 1;
    0602
    0603     if strcmp(handles.plotmode,'spectra_dt')
    0604          cmap =  gray(256);
    0605         [SFull t f]= mtdspecgramc(diff(data),handles.movingwin,0,params); SFull=SFull';
    0606     elseif strcmp(handles.plotmode,'spectra_df')
    0607           cmap =  gray(256);
    0608         [SFull t f]= mtdspecgramc(diff(data),handles.movingwin,pi/2,params); SFull=SFull';
    0609     end
    0610 end
    0611
    0612 if strcmp(handles.plotmode,'spectra') || strcmp(handles.plotmode,'spectra_dt') || strcmp(handles.plotmode,'spectra_df')
    0613
    0614     cmap(1,:) = [1, 1, 1];
    0615     colormap(cmap);
    0616
    0617     SFmin = min(min(SFull));
    0618     SFmax = max(max(SFull));
    0619     SFull = uint8(1 + round(255 * (SFull-SFmin) / (SFmax-SFmin)));
    0620
    0621     hi = image(tfull + segment.start - handles.specpad,f,SFull);
    0622     set(hi,'ButtonDownFcn',{@PlotModeCallBack});
    0623
    0624     axis xy;
    0625
    0626     hline1 = line([segment.start segment.start],[f(1) max(f)],'Color',[0 0 0],'LineWidth',3);
    0627     hline2 = line([segment.end segment.end],[f(1),max(f)],'Color',[0 0 0],'LineWidth',3);
    0628
    0629 else
    0630
    0631 % xlim([tfull(1) tfull(length(tfull))] + segment.start - handles.specpad);
    0632
    0633 hp = plot(segment.start - handles.specpad + [0:length(data)-1] / handles.Fs, data);
    0634 set(handles.ToClassifyAxes,'YLim',[-5 5]);
    0635 set(hp,'ButtonDownFcn',{@PlotModeCallBack});
    0636 axis tight;
    0637
    0638 dataspan = [min(data) max(data)];
    0639
    0640 hline1 = line([segment.start segment.start],dataspan,'Color',[0 0 0],'LineWidth',3);
    0641 hline2 = line([segment.end segment.end],dataspan,'Color',[0 0 0],'LineWidth',3);
    0642
    0643 end
    0644
    0645 axes(handles.ToClassifySmallAxes);
    0646 ispecFull = uint8(zeros(handles.ispecheight,handles.ismaxwidth));
    0647
    0648 ispecFull = copy_into(ispecFull,handles.IconList{handles.NextIndex},1,1);
    0649
    0650 if length(ispecFull(1,:)) > handles.ismaxwidth
    0651     ispecFull = ispecFull(:,1:handles.ismaxwidth);
    0652 end
    0653
    0654 if strcmp(get(handles.ZoomButton,'String'),'Zoom out')
    0655     f = [handles.lowerfreq handles.upperfreq];
    0656 end
    0657
    0658 tsmall = [handles.movingwin(1),handles.ismaxwidth * handles.movingwin(2) - handles.movingwin(1)];
    0659 %
    0660 % cmap = jet(256);
    0661 % cmap(1,:) = [1, 1, 1];
    0662 %
    0663 % colormap(cmap);
    0664
    0665 % [0 (handles.ismaxwidth * (segment.end - segment.start))/length(iconS(1,:))]
    0666 ih = image(tsmall,f,flipud(ispecFull));
    0667 axis xy;
    0668 ;
    0669
    0670 function PlotModeCallBack(src,eventdata)
    0671 % A Function for handling clicks to the axes
    0672     handles = guidata(gcbo);
    0673
    0674     handles.plotmodevalue = handles.plotmodevalue + 1;
    0675
    0676     if handles.plotmodevalue > length(handles.plotmodes)
    0677         handles.plotmodevalue = 1;
    0678     end
    0679
    0680     handles.plotmode = handles.plotmodes{handles.plotmodevalue};
    0681     handles=get_and_plot(handles, handles.segments(handles.NextIndex));
    0682
    0683     guidata(gcf,handles);
    0684
    0685 function handles=ConfigureSpecPlot(handles)
    0686 % Handles the gui configuration of the plotting
    0687 segment = handles.segments(handles.NextIndex);
    0688 if not(exist(segment.specfilename)) || handles.recompute
    0689     precompute_spectra(handles,segment);
    0690 end
    0691
    0692 set(handles.ToClassifyPanel,'Title',['Segment ' num2str(handles.NextIndex) '/' num2str(handles.nsegments)])
    0693
    0694 segmentstatus = ['File: "' segment.wavfile '"; Segment length ' num2str(segment.end - segment.start,3)];
    0695
    0696 set(handles.SegmentText,'String',segmentstatus);
    0697 handles = get_and_plot(handles, segment);
    0698 guidata(gcbo,handles);
    0699 ;
    0700
    0701 function NextSpectraButton_Callback(hObject, eventdata, handles)
    0702 % Moves the segment viewer forward one segment
    0703 handles.NextIndex = handles.NextIndex + 1;
    0704 if handles.NextIndex == handles.nsegments
    0705     set(handles.NextSpectraButton,'Enable','off');
    0706 end
    0707
    0708 if handles.NextIndex > 1
    0709     set(handles.PreviousSpectraButton,'Enable','on');
    0710 end
    0711
    0712 handles=ConfigureClassSegment(handles);
    0713 handles=ConfigureSpecPlot(handles);
    0714 guidata(gcbo,handles);
    0715 ;
    0716
    0717 function PreviousSpectraButton_Callback(hObject, eventdata, handles)
    0718 % Moves the segment viewer backwards one segment
    0719 handles.NextIndex = handles.NextIndex - 1;
    0720
    0721 if handles.NextIndex == 1
    0722     set(handles.PreviousSpectraButton,'Enable','off');
    0723     set(handles.NextSpectraButton,'Enable','on');
    0724 end
    0725
    0726 if handles.NextIndex < handles.nsegments
    0727     set(handles.NextSpectraButton,'Enable','on');
    0728 end
    0729
    0730 handles=ConfigureClassSegment(handles);
    0731 handles=ConfigureSpecPlot(handles);
    0732
    0733 set(handles.NextSpectraButton,'Enable','off');
    0734 set(handles.NextSpectraButton,'Enable','on');
    0735 guidata(gcbo,handles);
    0736 ;
    0737
    0738 function PrecomputeButton_Callback(hObject, eventdata, handles)
    0739 % Call back for the precompute button. This acts to load the file from the directory
    0740
    0741 handles.directory = get(handles.DirectoryEditBox,'String');
    0742
    0743 % fprintf('creating syllable list\n');
    0744 %handles.segments = segments;
    0745 handles.classes = [];
    0746 set(handles.PrecomputeButton, 'Enable', 'off' );
    0747 handles.NextIndex = 1;
    0748
    0749 handles = Load_InitialSegments(hObject,handles);
    0750 handles.recompute = logical(0);
    0751
    0752 if handles.nsegments >= 1
    0753     handles=ConfigureClassSegment(handles);
    0754
    0755     handles = load_configuration(handles,handles.configfile);
    0756
    0757     if exist([handles.baseclassname '.dat']) && not(handles.configschanged)
    0758         load('-mat','specicons');
    0759         handles.IconList  = IconList;
    0760         data = read_syllable_database(handles);
    0761         handles = merge_syllable_database(handles,data);
    0762     else
    0763         handles = precompute_AllSpectra(handles);
    0764     end
    0765
    0766     %set(handles.ConfigureButton, 'Enable','off');
    0767     handles=ConfigureSpecPlot(handles);
    0768     handles=BrowseDirectory(handles);
    0769     handles.precomputed = logical(1);
    0770     set(handles.PlaySegmentButton, 'Enable', 'on' );
    0771     set(handles.NextSpectraButton, 'Enable', 'on' );
    0772     set(handles.ModePopupMenu,'Enable','on');
    0773     set(handles.SaveButton,'Enable','on');
    0774     set(handles.SaveItem,'Enable','on');
    0775     set(handles.PrecomputeButton, 'Enable', 'off' );
    0776     set(handles.CleanDirectoryItem, 'Enable', 'off' );
    0777     set(handles.LoadDirectoryButton,'Enable','off');
    0778     set(handles.LoadItem,'Enable','off');
    0779     set(handles.ZoomButton,'Enable','on');
    0780     set(handles.QuickModeButton,'Enable','on');
    0781     set(handles.CompareToggleButton,'Enable','on');
    0782     set(handles.ConfigureButton,'Enable','on');
    0783     set(handles.ConfigureItem,'Enable','on');
    0784     set(handles.AutoClassifyButton,'Enable','on');
    0785
    0786     handles.fixed = logical(0); % turn off fixed scaling
    0787
    0788     if not(strcmp(handles.segments(handles.NextIndex).class,'')) % Set the classification status
    0789         set(handles.ClassifyButton,'String','Declassify');
    0790     end
    0791
    0792 else
    0793     set(handles.PrecomputeButton, 'Enable', 'on' );
    0794 end
    0795 guidata(gcbo,handles);
    0796 ;
    0797
    0798 % --- Executes on button press in PlaySegmentButton.
    0799
    0800 function PlaySegmentButton_Callback(hObject, eventdata, handles)
    0801 % Plays the current segment in the segment viewer
    0802 % hObject    handle to PlaySegmentButton (see GCBO)
    0803 % eventdata  reserved - to be defined in a future version of MATLAB
    0804 % handles    structure with handles and user data (see GUIDATA)
    0805 segment = handles.segments(handles.NextIndex);
    0806 data = wavread(segment.wavfile,[round(handles.Fs * segment.start),round(handles.Fs * segment.end)]);
    0807 wavplay(data,handles.Fs,'async');
    0808
    0809
    0810 function CurrentFilenameEdit_Callback(hObject, eventdata, handles)
    0811
    0812 function CurrentFilenameEdit_CreateFcn(hObject, eventdata, handles)
    0813 if ispc
    0814     set(hObject,'BackgroundColor','white');
    0815 else
    0816     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
    0817 end
    0818
    0819
    0820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0821 % Functions for viewing spectra icon  %
    0822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0823
    0824 function newwidth = SmallAxes_width(handles)
    0825 position1 = get(handles.ToClassifySmallAxes,'Position');
    0826 position2 = get(handles.ClassifiedAxes,'Position');
    0827
    0828 newwidth =  round(position1(3) *(handles.classified_width / position2(3)));
    0829
    0830 function iconS = iconify_spec(S,height)
    0831 % Take a large spectra with high frequency bandwidth and reduce the height
    0832 % by pixel averaging
    0833     Ssize = size(S);
    0834     iconS = zeros(height,Ssize(2));
    0835
    0836     % averaging of values to reduce size
    0837     rf = floor(Ssize(1)/height);
    0838
    0839     for i = 1:(height-1)
    0840         for j = 1 : Ssize(2)
    0841             iconS(i,j) = sum(S(((i-1)*rf)+1:i*rf,j))/rf;
    0842         end
    0843     end
    0844
    0845     for j = 1 : Ssize(2) % take care of the last row by also pixel averaging
    0846         iconS(height,j) = mean(S(rf*(height-1) : Ssize(1),j));
    0847     end
    0848     iconS = flipud(iconS);
    0849
    0850     % Rescaling of values
    0851     maxintense = max(max(iconS));
    0852     minintense = min(min(iconS));
    0853
    0854     iconS=uint8(1 + round(255 * (iconS-minintense)/(maxintense-minintense)));
    0855
    0856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0857 % Functions for loading in images %
    0858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0859
    0860 function destination = copy_into(destination,source,r,c)
    0861 % This copies an image into another image
    0862 % Two problems: one it can be optimized by removing the nested for loops
    0863 % two there is an indexing bug which returns a one pixel larger image
    0864 sized = size(destination);
    0865 sizes = size(source);
    0866
    0867 destination(r:r+sizes(1)-1,c:c+sizes(2)-1) = source(:,:);
    0868
    0869 % for i = 1:sizes(1)
    0870 %     for j = 1:sizes(2)
    0871 %         destination(r+i,c+j) = source(i,j);
    0872 %     end
    0873 % end
    0874 % ;
    0875
    0876 function positions = position_images(height,width,images_dim,xspacer,yspacer)
    0877 % This function returns a matrix consisting of two rows with the xy
    0878 % position for images.
    0879 % The function also assumes that the image's height is not restricted this
    0880 % allows for easier scrolling
    0881 % The function assumes that all images are of the same height
    0882 % height in pixels of the original
    0883 % width in pixels of the original
    0884 % images
    0885 % xspacer in pixels for the horizontal space between images
    0886 % yspacer is the next height of the image
    0887 % image height is the fixed height of the images
    0888
    0889 number_images = length(images_dim(:,1));
    0890 imageheight = images_dim(1);
    0891
    0892 currentx = xspacer;
    0893 currenty = yspacer;
    0894
    0895 positions = zeros(number_images,2);
    0896
    0897 for i = 1:number_images
    0898     if (currentx + images_dim(i,2) + xspacer) > width % start a new row
    0899         currentx = xspacer;
    0900         currenty = currenty + imageheight + yspacer;
    0901         positions(i,:) = [currenty currentx];
    0902         currentx = currentx + images_dim(i,2) + xspacer;
    0903     else
    0904         positions(i,:) = [currenty currentx];
    0905         currentx = currentx + images_dim(i,2) + xspacer;
    0906     end
    0907     %positions(i,:) = [currenty currentx];
    0908 end
    0909
    0910 % function image_matrix = place_images_into(image_matrix, image_list, position_list)
    0911 % % Place images into a matrix
    0912 % number_images = length(image_list);
    0913 %
    0914 % for i = 1:number_images
    0915 %     theimage = image_list{i};
    0916 %     image_matrix  = copy_into(image_matrix, theimage, position_list(i,1), position_list(i,2));
    0917 % end
    0918 % ;
    0919
    0920 function image_dim = get_image_sizes(images)
    0921 % Returns an array of image sizes
    0922 number_images = length(images);
    0923 image_dim = zeros(number_images,2);
    0924 for i = 1:number_images
    0925     image_dim(i,:) = size(images{i});
    0926 end
    0927 ;
    0928
    0929 function image_matrix = place_images_into(image_matrix, image_list, position_list)
    0930 % Place images into a matrix
    0931 number_images = length(image_list);
    0932
    0933 for i = 1:number_images
    0934     theimage = image_list{i};
    0935     image_matrix  = copy_into(image_matrix, theimage, position_list(i,1), position_list(i,2));
    0936 end
    0937 ;
    0938
    0939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0940 % Functions for manipulating and plotting spectra icons    %
    0941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0942
    0943 function IconList=get_SpecIcons(handles)
    0944 IconList = {};
    0945 status = 0;
    0946 for i = 1:handles.nsegments
    0947     load('-mat',handles.segments(i).specfilename);
    0948     IconList{i} = iconS;
    0949 end
    0950 save('specicons','IconList','-mat'); % temp code for saving
    0951
    0952
    0953 function handles = plot_classified_axes(handles, image_list, position_list)
    0954 % Low level drawing of the classified axes
    0955 handles.blank = logical(0);
    0956 handles.classmatrix = uint8(zeros(handles.classified_height,handles.classified_width));
    0957 axes(handles.ClassifiedAxes);
    0958 handles.classmatrix = place_images_into(handles.classmatrix,image_list,position_list);
    0959 set(handles.ClassifiedAxes,'XTick',[]);
    0960 set(handles.ClassifiedAxes,'YTick',[]);
    0961 handles.max_width = length(handles.classmatrix(1,:));
    0962
    0963 if  handles.max_width > handles.classified_width
    0964     set(handles.SliderClassified,'Min',0);
    0965     set(handles.SliderClassified,'Max',handles.max_width - handles.classified_width);
    0966     set(handles.SliderClassified,'enable','on');
    0967     handles.endx = handles.classified_width;
    0968 else
    0969     set(handles.SliderClassified,'enable','off')
    0970     handles.startx = 1;
    0971     handles.endx = handles.classified_width;
    0972 end
    0973
    0974 classview = handles.classmatrix(:,handles.startx:handles.endx); % will cut overhang
    0975 handles.hiclass = image(classview);
    0976 set(handles.hiclass,'ButtonDownFcn',{@ClassifyAxesClickCallBack});
    0977 set(handles.ClassifiedAxes,'XTick',[]);
    0978 set(handles.ClassifiedAxes,'YTick',[]);
    0979
    0980 setrowbuttons(handles);
    0981
    0982 function handles = reposition_images(handles, image_list)
    0983 % this is a lower level function which is called to reposition the images.
    0984 % this would be called from higher level functions when images are added,
    0985 % deleted, or a new list of images needs to be loaded.
    0986
    0987 % initialize the handles for the images
    0988 handles.nimages = length(image_list);
    0989 handles.images_dim = get_image_sizes(image_list);
    0990
    0991 handles.positions = position_images(handles.classified_height,handles.classified_width,handles.images_dim,handles.xspacer,handles.yspacer);
    0992 handles.cnrows = length(unique(handles.positions(:,1)));
    0993
    0994 % Setup the first page view
    0995 handles.number_rows = floor(handles.classified_height / (handles.ispecheight + handles.yspacer));
    0996 handles.startpage = 1;
    0997 handles.endpage = 0;
    0998
    0999 for i = 1 : handles.number_rows
    1000     handles.endpage = next_row_end(handles.positions,handles.endpage);
    1001 end
    1002
    1003 %guidata(gcbo,handles);
    1004 ;
    1005
    1006 function nrow = which_row(positions,index)
    1007
    1008 nrow = 1;
    1009 i = 2;
    1010 while i <= index
    1011     if not(positions(i,1) == positions(i-1,1))
    1012         nrow = nrow + 1;
    1013     end
    1014     i = i + 1;
    1015 end
    1016
    1017 function cpositions = get_curr_position(handles)
    1018 % Setups the current view of the positions
    1019     cpositions = handles.positions(handles.startpage:handles.endpage,:); % get the current view
    1020     cpositions(:,1) = cpositions(:,1) - cpositions(1,1) + handles.yspacer;
    1021     cpositions(:,2) = cpositions(:,2) - (handles.startx - 1);
    1022 ;
    1023
    1024 function cposition = next_row_start(positions,cposition)
    1025 % Computes the position of the next row if the row based on the positions matrix
    1026 % it computes the position where the row starts
    1027     npos = length(positions);
    1028     i = cposition;
    1029     while  (i <= npos) && positions(i,1) == positions(cposition,1)
    1030         i = i + 1;
    1031     end
    1032     if i < npos % make sure the row numbers match
    1033         cposition = i;
    1034     end
    1035     ;
    1036
    1037 function cposition = next_row_end(positions,cposition)
    1038 % Computes the position of the next row if the row based on the positions matrix
    1039 % it computes the last position before a new row starts
    1040     npos = length(positions(:,1));
    1041     if cposition < npos % not at the last row
    1042         i = cposition + 1;
    1043         while (i < npos) && (positions(i,1) == positions(cposition+1,1))
    1044             i = i + 1;
    1045         end
    1046         if (positions(cposition + 1) == positions(npos))
    1047             cposition = npos; % handle the condition that you are now at the last row
    1048         else
    1049             cposition = i - 1; % make sure the row numbers match
    1050         end
    1051     else % handles the condition you are already at the last row
    1052         cposition = npos;
    1053     end
    1054     ;
    1055
    1056
    1057 function handles = row_forward(handles)
    1058 % Moves the row forward in the classifiedaxes/browser view
    1059     startpage = next_row_start(handles.positions,handles.startpage);
    1060     endpage = next_row_end(handles.positions,handles.endpage);
    1061
    1062     if not(endpage == handles.endpage) % indicates you are not at the last page
    1063         handles.startpage = startpage;
    1064         handles.endpage = endpage;
    1065     end
    1066 %     guidata(gcbo,handles);
    1067   ;
    1068
    1069 function cposition = previous_row_start(positions,cposition)
    1070 % Computes the position of the previous row if the row based on the positions matrix
    1071 % it computes the position where the row starts
    1072     npos = length(positions(:,1));
    1073     if cposition > 1
    1074         i = cposition - 1;
    1075         while (i > 1) && (positions(i,1) == positions(cposition-1,1))
    1076             i = i - 1;
    1077         end
    1078         if (i > 1) && (cposition ~= 2)
    1079             cposition = i + 1;
    1080         else
    1081             cposition = 1;
    1082         end
    1083     else
    1084         cposition = 1; % in case things get missed up and neg index
    1085     end
    1086     ;
    1087
    1088 function cposition = previous_row_end(positions,cposition)
    1089     npos = length(positions(:,1));
    1090
    1091     if cposition > 1
    1092         i = cposition;
    1093         while (i > 1) && (positions(i,1) == positions(cposition,1))
    1094             i = i - 1;
    1095         end
    1096         if i > 1;
    1097             cposition = i;
    1098         else
    1099             cposition = 1;
    1100         end
    1101     else
    1102         cposition = 1;
    1103     end
    1104     ;
    1105
    1106 function nrows = number_of_rows(handles)
    1107 % Computes the number of rows in the current view
    1108 nrows = length(unique(handles.positions(handles.startpage:handles.endpage,1)));
    1109
    1110 function handles = row_backward(handles)
    1111 % Moves the row backwards in the classifiedaxes/browser view
    1112     startpage = previous_row_start(handles.positions,handles.startpage);
    1113     endpage = previous_row_end(handles.positions,handles.endpage);
    1114
    1115     if  number_of_rows(handles) < handles.number_rows % indicates you are not at the last page
    1116          handles.startpage = startpage;
    1117          handles.endpage = length(handles.positions(:,1));
    1118     elseif handles.startpage == 1;
    1119         handles.startpage = 1;
    1120         handles.endpage = handles.endpage;
    1121     else
    1122         handles.startpage = startpage;
    1123         handles.endpage = endpage;
    1124     end
    1125 %     guidata(gcbo,handles);
    1126   ;
    1127
    1128 function handles = BrowseDirectory(handles)
    1129 % This function should be called only after precompute has been called
    1130 % it relies on their being a specicon file in the directory
    1131 %
    1132 % The function takes the current segments in the directory and loads their specicons
    1133 % into memory because the segments and icons are created in their order the
    1134 % order matches. This will need to be worked out better for the
    1135 % classification algorithms.
    1136
    1137 %load('-mat', 'specicons');
    1138 set_status(handles, ['Viewing all ', num2str(handles.nsegments),' segments']);
    1139 handles.mapindex = [1:handles.nsegments];
    1140 handles.image_list = handles.IconList;
    1141 handles = reposition_images(handles, handles.image_list);
    1142 handles.cpositions =  get_curr_position(handles);
    1143 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1144 handles.mode='browse';
    1145
    1146 %guidata(gcbo,handles);
    1147
    1148
    1149 % --- Executes on button press in NextRowButton.
    1150 function NextRowButton_Callback(hObject, eventdata, handles)
    1151 % hObject    handle to NextRowButton (see GCBO)
    1152 % eventdata  reserved - to be defined in a future version of MATLAB
    1153 % handles    structure with handles and user data (see GUIDATA)
    1154
    1155 if handles.cnrows > 1
    1156     handles.startx = 1; % if you have been scrolling reset to defaults
    1157     handles.endx = handles.classified_width;
    1158     set(handles.SliderClassified, 'Value',0);
    1159     handles = row_forward(handles);
    1160     handles.cpositions =  get_curr_position(handles);
    1161     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1162 end
    1163 guidata(gcbo,handles);
    1164
    1165 % --- Executes on button press in PreviousRowButton.
    1166 function PreviousRowButton_Callback(hObject, eventdata, handles)
    1167 % hObject    handle to PreviousRowButton (see GCBO)
    1168 % eventdata  reserved - to be defined in a future version of MATLAB
    1169 % handles    structure with handles and user data (see GUIDATA)
    1170
    1171 if handles.cnrows > 1
    1172     handles.startx = 1;
    1173     handles.endx = handles.classified_width;
    1174     set(handles.SliderClassified, 'Value',0);
    1175     handles = row_backward(handles);
    1176     handles.cpositions =  get_curr_position(handles);
    1177     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1178 end
    1179 guidata(gcbo,handles);
    1180
    1181 % --- Executes on button press in LoadDirectoryButton.
    1182 function LoadDirectoryButton_Callback(hObject, eventdata, handles)
    1183 % hObject    handle to LoadDirectoryButton (see GCBO)
    1184 % eventdata  reserved - to be defined in a future version of MATLAB
    1185 % handles    structure with handles and user data (see GUIDATA)
    1186
    1187 %directoryname = uigetdir('./','Change directory');
    1188
    1189 directoryname = uigetdir;
    1190
    1191 if not(directoryname == 0)
    1192     handles.directory = directoryname;
    1193     set(handles.DirectoryEditBox, 'String',directoryname);
    1194     cd(handles.directory); % this we will need to change
    1195 end
    1196 guidata(gcbo,handles);
    1197 ;
    1198
    1199 function im_index = coordinate2index(handles,xpos,ypos)
    1200 % For the current images displayed tests if pointer position is in an image
    1201 % returns the index for that image based on a left to right ordering on
    1202 % that page
    1203 % First check if the coordinate is totally out of the range
    1204 if (xpos < 0) || (ypos < 0) || (ypos > handles.classified_height)  || (xpos > handles.classified_width)
    1205     im_index = 0;
    1206 else
    1207     im_index = 0;
    1208     npos = length(handles.cpositions(:,1));
    1209     i = 1;
    1210     while (i <= npos) && (im_index < 1)
    1211         if (xpos >= handles.cpositions(i,2)) && (xpos <= (handles.cpositions(i,2) + handles.images_dim(handles.startpage + (i-1), 2)))
    1212             if (ypos >= handles.cpositions(i,1)) && (ypos <= (handles.cpositions(i,1) + handles.images_dim(handles.startpage + (i-1),1)))
    1213                 im_index = i;
    1214             end
    1215         end
    1216         i = i+1;
    1217     end
    1218 end
    1219 ;
    1220
    1221 function setnavigationbuttons(handles)
    1222 % Sets the navigation buttons based on where the pointer is
    1223
    1224 if not(handles.quickmode)
    1225
    1226 if handles.NextIndex == handles.nsegments
    1227     set(handles.PreviousSpectraButton,'Enable','off');
    1228     set(handles.NextSpectraButton,'Enable','off');
    1229 elseif handles.NextIndex == handles.nsegments
    1230     set(handles.NextSpectraButton,'Enable','off');
    1231     set(handles.PreviousSpectraButton,'Enable','on');
    1232 elseif handles.NextIndex == 1
    1233     set(handles.PreviousSpectraButton,'Enable','off');
    1234     set(handles.NextSpectraButton,'Enable','on');
    1235 elseif (handles.NextIndex > 1) && (handles.NextIndex < handles.nsegments)
    1236     set(handles.PreviousSpectraButton,'Enable','on');
    1237     set(handles.NextSpectraButton,'Enable','on');
    1238
    1239 end
    1240
    1241 end
    1242
    1243 function setrowbuttons(handles)
    1244
    1245 if handles.startpage == 1
    1246     set(handles.PreviousRowButton,'Enable','off');
    1247 elseif handles.startpage > 1
    1248     set(handles.PreviousRowButton,'Enable','on');
    1249 end
    1250
    1251 if handles.endpage == length(handles.positions) % You are the last row
    1252     set(handles.NextRowButton,'Enable','off');
    1253 elseif handles.cnrows <= handles.number_rows
    1254     set(handles.NextRowButton,'Enable','off');
    1255 elseif handles.endpage < length(handles.positions)
    1256     set(handles.NextRowButton,'Enable','on');
    1257 end
    1258
    1259 function DummyClassifyAxesClickCallBack(src,eventdata,handles)
    1260 % When the image is blank this allow you to select out of the class view
    1261 set(handles.ClassifyButton,'Enable','on');
    1262 set(handles.NewClassButton,'Visible','off');
    1263 set(handles.NextSpectraButton,'Enable','on');
    1264 set(handles.PreviousSpectraButton,'Enable','on');
    1265 set(handles.ModePopupMenu,'Enable','on');
    1266 set(handles.AutoClassifyButton,'Enable','on');
    1267 set(handles.QuickModeButton,'Enable','on');
    1268 set(handles.CompareToggleButton,'Enable','on');
    1269 handles.submode = 'select';
    1270 setnavigationbuttons(handles);
    1271 guidata(gcbo,handles);
    1272
    1273
    1274 function ClassifyAxesClickCallBack(src,eventdata)
    1275 % A Function for handling clicks to the axes
    1276     handles = guidata(gcbo);
    1277 %     handles.mode
    1278     %handles.submode
    1279     %fprintf('\n');
    1280
    1281     pos = get(handles.ClassifiedAxes,'CurrentPoint');
    1282     cposition = coordinate2index(handles,pos(1,1),pos(1,2));
    1283
    1284     if handles.quickmode
    1285     if cposition == 0 % Selecting in the outside takes you out of classification mode
    1286             set_status(handles,'');
    1287         else % You have selected an icon
    1288             handles.startx = 1; % if you have been scrolling reset to defaults
    1289             handles.endx = handles.classified_width;
    1290             set(handles.SliderClassified,'Value',0);
    1291             class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
    1292             handles.segments(handles.NextIndex).class = class.name;
    1293             handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers = handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers + 1;
    1294             handles = jump_to_unclassified(handles);
    1295             handles = configureclassview(handles,'select-class');
    1296             if handles.lastsegment == handles.NextIndex % no more unclassified segments
    1297                 handles = quick_mode_exit(handles);
    1298                 set(handles.QuickModeButton,'Value',0);
    1299                 handles.quickmode = not(handles.quickmode);
    1300             end
    1301         end
    1302     else % quick classify mode is off
    1303
    1304
    1305     if strcmp(handles.mode,'browse') && (cposition > 0)
    1306         handles.NextIndex = handles.mapindex((cposition - 1) + handles.startpage);
    1307         handles=ConfigureClassSegment(handles);
    1308         handles=ConfigureSpecPlot(handles);
    1309     else
    1310          %fprintf('%i\n', coordinate2index(handles,pos(1,1),pos(1,2)));
    1311          %fprintf('%i, %i\n\n', pos(1,1),pos(1,2));
    1312          ;
    1313     end
    1314
    1315     if strcmp('class-members',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
    1316         handles.NextIndex = handles.mapindex((cposition - 1) + handles.startpage);
    1317         handles=ConfigureClassSegment(handles);
    1318         handles=ConfigureSpecPlot(handles);
    1319     end
    1320
    1321     %Show all members of a specific class
    1322     if strcmp('class-view',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
    1323         handles.startx = 1; % if you have been scrolling reset to defaults
    1324         handles.endx = handles.classified_width;
    1325         set(handles.SliderClassified,'Value',0);
    1326 %         set(handles.CompareToggleButton,'Visible','off');
    1327         cindex = handles.mapindex(cposition + (handles.startpage - 1));
    1328         class = handles.classes(cindex);
    1329         handles.lastclass = cindex;
    1330         handles = configureclassmembers(handles,class.name);
    1331         handles.mode = 'class-members';
    1332         handles.submode = 'select';
    1333         handles = SetModePopupMenu(handles,'class members');
    1334         set(handles.TypifyClassButton,'Visible','on');
    1335         set(handles.RemoveClassButton,'Visible','off');
    1336         set(handles.NextClassButton,'Visible','on');
    1337         set(handles.RenameClassButton,'Visible','on');
    1338         set_status(handles, ['Viewing ' num2str(length(handles.mapindex)),' members of ' class.name]);
    1339     end
    1340
    1341     if strcmp('class-view',handles.mode) && strcmp('select-class',handles.submode)
    1342         if cposition == 0 % Selecting in the outside takes you out of classification mode
    1343             set(handles.ClassifyButton,'Enable','on');
    1344             set(handles.NewClassButton,'Visible','off');
    1345             set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    1346
    1347         else % You have selected an icon
    1348             handles.startx = 1; % if you have been scrolling reset to defaults
    1349             handles.endx = handles.classified_width;
    1350             set(handles.SliderClassified,'Value',0);
    1351             class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
    1352             handles.segments(handles.NextIndex).class = class.name;
    1353             handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers = handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers + 1;
    1354             set(handles.ClassifyButton,'String','Declassify');
    1355             handles = SetModePopupMenu(handles,'class members');
    1356             handles = configureclassmembers(handles,class.name);
    1357             handles.mode = 'class-members';
    1358             handles.submode = 'select';
    1359             set_status(handles,['Classified segment as ' class.name]);
    1360         end
    1361         set(handles.CompareToggleButton,'Enable','on');
    1362         set(handles.QuickModeButton,'Enable','on');
    1363         set(handles.AutoClassifyButton,'Enable','on');
    1364         set(handles.ClassifyButton,'Enable','on');
    1365         set(handles.NewClassButton,'Visible','off');
    1366         set(handles.NextSpectraButton,'Enable','on');
    1367         set(handles.PreviousSpectraButton,'Enable','on');
    1368         set(handles.ModePopupMenu,'Enable','on');
    1369         set(handles.SortText,'Visible','off');
    1370         set(handles.SortPopupMenu,'Visible','off');
    1371         handles.submode = 'select';
    1372     end
    1373
    1374     if strcmp(handles.mode,'class-members') && strcmp(handles.submode,'typify')
    1375         if cposition == 0
    1376             set(handles.TypifyClassButton, 'Enable','on');
    1377         else
    1378             handles.startx = 1; % if you have been scrolling reset to defaults
    1379             handles.endx = handles.classified_width;
    1380             set(handles.SliderClassified,'Value',0);
    1381             sindex = handles.mapindex(cposition + (handles.startpage - 1));
    1382             cindex = returnclassindex(handles,handles.segments(sindex).class);
    1383             handles.classes(cindex).specfilename = handles.segments(sindex).specfilename;
    1384             handles.classes(cindex).length = handles.segments(sindex).end - handles.segments(sindex).start;
    1385             handles.classes(cindex).index = sindex;
    1386             %load('-mat','specicons');
    1387             handles.classes(cindex).iconS = handles.IconList{sindex};
    1388             handles.subclass = 'xxx';
    1389             set(handles.TypifyClassButton, 'Enable','on');
    1390             set_status(handles,'');
    1391         end
    1392     end
    1393
    1394     if strcmp('class-view', handles.mode) && strcmp('compare',handles.submode)
    1395         if cposition == 0
    1396             handles.mode = 'class-view';
    1397             handles.submode = 'select';
    1398             set(handles.CompareToggleButton,'Enable','on');
    1399             set(handles.RemoveClassButton,'Enable','on');
    1400             set(handles.NextSpectraButton,'Enable','on');
    1401             set(handles.PreviousSpectraButton,'Enable','on');
    1402             %set(handles.ModePopupMenu,'Enable','on');
    1403         else
    1404             handles.mode = 'comparison';
    1405             if strcmp(handles.segments(handles.NextIndex).class,'')
    1406                 set(handles.ClassifyButton,'Enable','on');
    1407             end
    1408             handles.startx = 1; % if you have been scrolling reset to defaults
    1409             handles.endx = handles.classified_width;
    1410             set(handles.SliderClassified,'Value',0);
    1411             cindex = handles.mapindex(cposition + (handles.startpage - 1));
    1412             handles.image_list = {};
    1413             handles.lastclass = cindex;
    1414             handles.image_list{2} = handles.classes(cindex).iconS;
    1415             %load('-mat','specicons');
    1416             handles.image_list{1} = handles.IconList{handles.NextIndex};
    1417
    1418             set_status(handles,['Comparing to ' handles.classes(cindex).name]);
    1419
    1420             handles = reposition_images(handles, handles.image_list);
    1421             handles.cpositions =  get_curr_position(handles);
    1422             handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1423             handles.submode = 'xxx';
    1424         end
    1425     end
    1426
    1427
    1428     if strcmp(handles.mode,'class-view') && strcmp(handles.submode,'remove-class')
    1429         if cposition == 0
    1430             handles.submode = 'select';
    1431             set(handles.RemoveClassButton, 'Enable','on');
    1432             set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    1433         else
    1434             cindex = handles.mapindex(cposition + (handles.startpage - 1));
    1435             classname = handles.classes(cindex).name;
    1436
    1437             answer = questdlg(['Remove class ' classname]);
    1438
    1439             if strcmp(answer,'Yes')
    1440                 handles.startx = 1; % if you have been scrolling reset to defaults
    1441                 handles.endx = handles.classified_width;
    1442                 set(handles.SliderClassified,'Value',0);
    1443                 for i = 1:handles.nsegments
    1444                     if strcmp(classname,handles.segments(i).class)
    1445                         handles.segments(i).class = '';
    1446                     end
    1447                 end
    1448
    1449                 if handles.nclasses > 1
    1450                     handles.classes = [handles.classes(1:(cindex-1)) handles.classes((cindex+1):handles.nclasses)];
    1451                     handles.nclasses = handles.nclasses - 1;
    1452                     handles = configureclassview(handles,'select');
    1453
    1454                     set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    1455                 else
    1456                     handles.classes = [];
    1457                     handles.nclasses = 0;
    1458                     handles.image_list = {};
    1459                     set_status(handles,'');
    1460                     set(handles.RemoveClassButton,'Visible','off');
    1461                     handles.submode = 'xxx';
    1462                     handles = blankaxes(handles);
    1463                 end
    1464
    1465                 if strcmp(handles.segments(handles.NextIndex).class,'')
    1466                     set(handles.ClassifyButton,'String','Classify');
    1467                 end
    1468                 set(handles.RemoveClassButton, 'Enable','on');
    1469             else
    1470                 handles.submode = 'select';
    1471                 set(handles.RemoveClassButton, 'Enable','on');
    1472                 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    1473             end
    1474         end
    1475     end
    1476
    1477     end
    1478
    1479     if not(strcmp(handles.mode,'comparison'))
    1480         setnavigationbuttons(handles);
    1481     end
    1482 %     handles.mode
    1483 %     handles.submode
    1484     guidata(gcf,handles);
    1485
    1486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1487 %  Functions for setting up the classview  %
    1488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1489
    1490 function handles = configureclassview(handles,submode)
    1491 % Configures the class-view for selecting classes
    1492     handles.mode = 'class-view';
    1493     handles.submode = submode;
    1494 %     if not(handles.quickmode)
    1495 %         set_status(handles, ['Select a class']);
    1496 %     end
    1497     handles.mapindex = [1 : handles.nclasses];
    1498
    1499     if strcmp(handles.sortclass, 'popularity')
    1500         handles.mapindex = sortindexbypop(handles);
    1501     elseif strcmp(handles.sortclass,'length');
    1502         handles.mapindex = sortindexbylength(handles);
    1503     else
    1504         handles.mapindex = [1 : handles.nclasses];
    1505     end
    1506     handles = cindex2imagelist(handles);
    1507     handles = reposition_images(handles, handles.image_list);
    1508
    1509     if (strcmp(handles.sortclass,'length') && strcmp(handles.submode,'select-class')) || (strcmp(handles.sortclass,'length') && strcmp(handles.submode,'compare'))
    1510         % jump to the segment with the closest size match
    1511         i = 1;
    1512         while (i <= handles.nclasses) && (handles.classes(handles.mapindex(i)).length >= (handles.segments(handles.NextIndex).end - handles.segments(handles.NextIndex).start))
    1513             i = i + 1;
    1514         end
    1515         cnrow = which_row(handles.positions,i-1); % get the current row
    1516
    1517         if cnrow > handles.number_rows % The closes size segment is not in view
    1518             for i = 1:(cnrow - handles.number_rows) % matching size row is last
    1519                 handles = row_forward(handles);
    1520             end
    1521
    1522             if not(handles.endpage == length(handles.positions)) % if not at the last row position so that larger and smaller rows match
    1523                 nrows = floor(handles.number_rows / 2);
    1524                 for i = 1:nrows
    1525                     handles = row_forward(handles);
    1526                 end
    1527             end
    1528
    1529
    1530         end
    1531     end
    1532
    1533     handles.cpositions = get_curr_position(handles);
    1534     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1535     %guidata(gcbo,handles);
    1536 ;
    1537
    1538 function handles = SetModePopupMenu(handles,viewstring)
    1539 popmodes = get(handles.ModePopupMenu,'String');
    1540
    1541 find_index = 0;
    1542 i = 1;
    1543 while (i <= length(popmodes)) && not(strcmp(popmodes(i),viewstring))
    1544     i = i + 1;
    1545 end
    1546
    1547 if i <= length(popmodes) % Don't do anything if the string cannot be found
    1548     set(handles.ModePopupMenu,'Value',[i]);
    1549 end
    1550
    1551 % --- Executes on selection change in ModePopupMenu.
    1552 function ModePopupMenu_Callback(hObject, eventdata, handles)
    1553 % Configure call back
    1554 % hObject    handle to ModePopupMenu (see GCBO)
    1555 % eventdata  reserved - to be defined in a future version of MATLAB
    1556 % handles    structure with handles and user data (see GUIDATA)
    1557
    1558 % Hints: contents = get(hObject,'String') returns ModePopupMenu contents as cell array
    1559 %        contents{get(hObject,'Value')} returns selected item from ModePopupMenu
    1560
    1561 handles.startx = 1; % if you have been scrolling reset to defaults
    1562 handles.endx = handles.classified_width;
    1563 set(handles.SliderClassified,'Value',0);
    1564 %set(handles.CompareToggleButton,'Visible','off');
    1565 set(handles.RenameClassButton, 'Visible', 'off');
    1566
    1567 nmode = get(hObject,'Value');
    1568 modeview = get(hObject,'String');
    1569
    1570
    1571 if strcmp(modeview(nmode),'all')
    1572     handles.mode = 'browse';
    1573     handles.submode = 'select';
    1574     handles=BrowseDirectory(handles);
    1575     set(handles.RemoveClassButton,'Visible','off');
    1576     set(handles.TypifyClassButton, 'Visible', 'off');
    1577     set(handles.NextClassButton,'Visible','off');
    1578
    1579 elseif strcmp(modeview(nmode),'class view')
    1580     set(handles.NextClassButton,'Visible','off');
    1581     if handles.nclasses >= 1
    1582         handles = configureclassview(handles,'select');
    1583         handles.mode = 'class-view';
    1584         handles.submode = 'select';
    1585         set(handles.RemoveClassButton,'Visible','on');
    1586         set(handles.RemoveClassButton,'Enable','on');
    1587         set(handles.CompareToggleButton,'Visible','on');
    1588         set(handles.CompareToggleButton,'Enable','on');
    1589         set(handles.TypifyClassButton, 'Visible', 'off');
    1590         set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes'])
    1591     else % empty axes
    1592         handles = blankaxes(handles);
    1593         handles.mode = 'class-view';
    1594         handles.submode = 'xxx';
    1595         set_status(handles,'');
    1596     end
    1597 elseif strcmp(modeview(nmode),'unclassified') || (strcmp(handles.segments(handles.NextIndex).class,'') && strcmp(modeview(nmode),'class members'))
    1598     handles = configureclassmembers(handles,'');
    1599     set_status(handles,['A total of ' num2str(length(handles.mapindex)) ' unclassified segments ']);
    1600     handles = SetModePopupMenu(handles,'unclassified');
    1601     handles.mode = 'browse';
    1602     handles.submode = 'select';
    1603     set(handles.RemoveClassButton, 'Visible', 'off');
    1604     set(handles.TypifyClassButton,'Visible','off');
    1605     set(handles.NextClassButton,'Visible','off');
    1606 elseif strcmp(modeview(nmode),'class members')
    1607     handles = configureclassmembers(handles,handles.segments(handles.NextIndex).class);
    1608     set_status(handles,['Viewing ' num2str(length(handles.mapindex)) ' members of ' handles.segments(handles.NextIndex).class]);
    1609     handles.mode = 'class-members';
    1610     handles.submode = 'select';
    1611     handles.lastclass = get_class_index(handles,handles.segments(handles.NextIndex).class);
    1612     set(handles.TypifyClassButton,'Visible', 'on');
    1613     set(handles.RemoveClassButton, 'Visible', 'off');
    1614     set(handles.RenameClassButton,'Visible','on');
    1615     set(handles.NextClassButton,'Visible','on');
    1616 end
    1617 guidata(gcbo,handles);
    1618
    1619 % --- Executes during object creation, after setting all properties.
    1620 function ModePopupMenu_CreateFcn(hObject, eventdata, handles)
    1621 % hObject    handle to ModePopupMenu (see GCBO)
    1622 % eventdata  reserved - to be defined in a future version of MATLAB
    1623 % handles    empty - handles not created until after all CreateFcns called
    1624
    1625 % Hint: popupmenu controls usually have a white background on Windows.
    1626 %       See ISPC and COMPUTER.
    1627 if ispc
    1628     set(hObject,'BackgroundColor','white');
    1629 else
    1630     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
    1631 end
    1632
    1633 function set_status(handles, statusstring)
    1634     set(handles.SegInfoText,'String',statusstring);
    1635     set(handles.SegInfoText,'Visible','on');
    1636 ;
    1637
    1638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1639 % Functions for filtering by class type    %
    1640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1641
    1642 function handles = configureclassmembers(handles,classname)
    1643
    1644 handles.mapindex = select_class(handles,handles.segments,classname);
    1645
    1646 if length(handles.mapindex) > 0
    1647     handles.image_list = {};
    1648     %load('-mat','specicons');
    1649
    1650     for i = 1:length(handles.mapindex)
    1651         handles.image_list(i) = handles.IconList(handles.mapindex(i));
    1652     end
    1653     handles = reposition_images(handles, handles.image_list);
    1654     handles.cpositions =  get_curr_position(handles);
    1655     %
    1656     %handles.mode = 'class-members';
    1657     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    1658 %handles = SetModePopupMenu(handles,'class members');
    1659 else
    1660     handles = blankaxes(handles);
    1661     %handles.mode = 'class-view';
    1662     %handles.submode = 'select';
    1663     set_status(handles,'');
    1664 end
    1665 ;
    1666
    1667 function indexfilter = select_class(handles,segments,classname)
    1668 % Returns an index array of original addresses of segments which are members of a
    1669 % specified class
    1670 indexfilter = [];
    1671 nclassmembers = 0;
    1672 for i = 1:handles.nsegments
    1673     if strcmp(segments(i).class,classname)
    1674         nclassmembers = nclassmembers + 1;
    1675         indexfilter(nclassmembers) = i;
    1676     end
    1677 end
    1678
    1679 function cindex = get_class_index(handles,classname);
    1680 cindex = 0;
    1681 i = 1;
    1682 while (i <= handles.nclasses) && not(strcmp(handles.classes(i).name,classname))
    1683     i = i + 1;
    1684 end
    1685 cindex = i;
    1686
    1687 function value = mapind(index)
    1688 % Map the index value back to its original value
    1689 value = handles.mapindex(index);
    1690
    1691 %%&& not(strcmp(segments(i).class,''));
    1692 function write_syllable_database(handles)
    1693 filename = [handles.baseclassname '.dat'];
    1694 fid = fopen(filename,'wt');
    1695
    1696 classes = handles.classes;
    1697
    1698 if fid > -1
    1699     for i = 1:handles.nsegments
    1700         segment = handles.segments(i);
    1701         wavfile = segment.wavfile;
    1702         specfilename = segment.specfilename;
    1703         seg = [ num2str(segment.start) '\t' num2str(segment.end)];
    1704         classname = [ segment.class ];
    1705         typify = '';
    1706         nclasses = length(classes);
    1707         j = 1;
    1708         while (nclasses > 0) && (j <= nclasses) && not(strcmp(segment.specfilename,classes(j).specfilename))
    1709             j = j + 1;
    1710         end
    1711         if j <= length(classes) % found a match
    1712             classes = [classes(1:j-1) classes(j+1:nclasses)]; % shorten the classes
    1713             typify = '*'; % indicates that this is typological class
    1714         end
    1715         fprintf(fid,[specfilename '\t' wavfile '\t' seg '\t' classname '\t' typify '\n']);
    1716     end
    1717     fclose(fid);
    1718 end
    1719 ;
    1720
    1721 function data = read_syllable_database(handles)
    1722 filename = [handles.baseclassname '.dat'];
    1723 fid = fopen(filename,'rt');
    1724 data = textscan(fid,'%s %s %n %n %s %s', 'delimiter','\t');
    1725 data = [data(1), data(5), data(6)]; % throw out extra stuff which will be useful for external analysis
    1726 fclose(fid);
    1727 ;
    1728
    1729 function handles = merge_syllable_database(handles,data)
    1730 % Merge the syllable list with the loaded database
    1731
    1732 %load('-mat','specicons');
    1733 specfilenames = data{1};
    1734 classnames = data{2};
    1735 typifies = data{3};
    1736 ndata = length(specfilenames);
    1737 %classnum = 1;
    1738 handles.classes = [];
    1739 handles.nclasses = 0;
    1740 for i = 1:ndata
    1741     j=1; % allow for no matches and allow for
    1742     while (j < handles.nsegments) && not(strcmp(specfilenames(i),handles.segments(j).specfilename))
    1743         j = j + 1;
    1744     end
    1745     if j <= handles.nsegments
    1746         handles.segments(j).class = classnames{i};
    1747         if  strcmp(typifies(i),'*') % this is the type class
    1748             %classnum = classnum + 1;
    1749             class.specfilename = specfilenames{i};
    1750             class.name = classnames{i};
    1751             class.index = j;
    1752             class.length = handles.segments(j).end - handles.segments(j).start;
    1753             class.iconS = handles.IconList{j};
    1754             class.nmembers = 0; % will update shortly
    1755             handles.nclasses = handles.nclasses + 1;
    1756             handles.classes = [handles.classes class];
    1757         end
    1758     end
    1759 end
    1760
    1761 % Now that we have the classes defined update the number of members
    1762 for i = 1:handles.nclasses
    1763     for j = 1 : handles.nsegments
    1764         if strcmp(handles.classes(i).name,handles.segments(j).class)
    1765             handles.classes(i).nmembers = handles.classes(i).nmembers + 1;
    1766         end
    1767     end
    1768 end
    1769
    1770
    1771 % --- Executes on button press in SaveButton.
    1772 function SaveButton_Callback(hObject, eventdata, handles)
    1773 % hObject    handle to SaveButton (see GCBO)
    1774 % eventdata  reserved - to be defined in a future version of MATLAB
    1775 % handles    structure with handles and user data (see GUIDATA)
    1776
    1777 write_syllable_database(handles); % save the database
    1778 save_configuration(handles,handles.configfile); % save the current configuration
    1779
    1780
    1781 % --- Executes on slider movement.
    1782 function SliderClassified_Callback(hObject, eventdata, handles)
    1783 % hObject    handle to SliderClassified (see GCBO)
    1784 % eventdata  reserved - to be defined in a future version of MATLAB
    1785 % handles    structure with handles and user data (see GUIDATA)
    1786
    1787 % Hints: get(hObject,'Value') returns position of slider
    1788 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
    1789
    1790 xposition = round(get(hObject,'Value'));
    1791 %xposition
    1792 handles.startx = 1 + xposition;
    1793 handles.endx  = xposition + handles.classified_width;
    1794 handles.cpositions =  get_curr_position(handles);
    1795 classview = handles.classmatrix(:,handles.startx:handles.endx); % will cut overhang
    1796 axes(handles.ClassifiedAxes);
    1797 handles.hiclass = image(classview);
    1798
    1799 set(handles.hiclass,'ButtonDownFcn',{@ClassifyAxesClickCallBack});
    1800 set(handles.ClassifiedAxes,'XTick',[]);
    1801 set(handles.ClassifiedAxes,'YTick',[]);
    1802
    1803 guidata(hObject, handles);
    1804
    1805 % --- Executes during object creation, after setting all properties.
    1806 function SliderClassified_CreateFcn(hObject, eventdata, handles)
    1807 % hObject    handle to SliderClassified (see GCBO)
    1808 % eventdata  reserved - to be defined in a future version of MATLAB
    1809 % handles    empty - handles not created until after all CreateFcns called
    1810
    1811 % Hint: slider controls usually have a light gray background, change
    1812 %       'usewhitebg' to 0 to use default.  See ISPC and COMPUTER.
    1813 usewhitebg = 1;
    1814 if usewhitebg
    1815     set(hObject,'BackgroundColor',[.9 .9 .9]);
    1816 else
    1817     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
    1818 end
    1819
    1820 % --- Executes on selection change in SortPopupMenu.
    1821 function SortPopupMenu_Callback(hObject, eventdata, handles)
    1822 % hObject    handle to SortPopupMenu (see GCBO) eventdata  reserved - to be defined in a future version of MATLAB
    1823 % handles    structure with handles and user data (see GUIDATA)
    1824
    1825 % Hints: contents = get(hObject,'String') returns SortPopupMenu contents as cell array
    1826 %        contents{get(hObject,'Value')} returns selected item from SortPopupMenu
    1827
    1828 sortlist = get(hObject,'String');
    1829 sortn = get(hObject,'Value');
    1830 sortby = sortlist(sortn);
    1831
    1832 if strcmp(sortby,'original')
    1833     handles.sortclass = 'original';
    1834 elseif strcmp(sortby,'by length')
    1835     handles.sortclass = 'length';
    1836 elseif strcmp(sortby,'by popularity')
    1837     handles.sortclass = 'popularity';
    1838 end
    1839
    1840 handles = configureclassview(handles,handles.submode);
    1841
    1842 guidata(gcbo,handles);
    1843
    1844 % --- Executes during object creation, after setting all properties.
    1845 function SortPopupMenu_CreateFcn(hObject, eventdata, handles)
    1846 % hObject    handle to SortPopupMenu (see GCBO)
    1847 % eventdata  reserved - to be defined in a future version of MATLAB
    1848 % handles    empty - handles not created until after all CreateFcns called
    1849
    1850 % Hint: popupmenu controls usually have a white background on Windows.
    1851 %       See ISPC and COMPUTER.
    1852 if ispc
    1853     set(hObject,'BackgroundColor','white');
    1854 else
    1855     set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
    1856 end
    1857
    1858
    1859 function segments = rename_segments(segments,oldname,newname)
    1860
    1861 nsegments = length(segments);
    1862 for i = 1 : nsegments
    1863     if strcmp(segments(i).class,oldname)
    1864         segments(i).class = newname;
    1865     end
    1866 end
    1867
    1868 function cln = doesclassexist(classname,classes)
    1869 % tests whether the current class name already exists if does not exist
    1870 % returns 1 if it does exist returns 0
    1871
    1872 i = 1;
    1873 nclasses = length(classes);
    1874
    1875 while (i <= nclasses) && (strcmp(classname,classes(i).name))
    1876     i = i + 1;
    1877 end
    1878
    1879 if i <= nclasses
    1880     cln = i;
    1881 else
    1882     cln = 0;
    1883 end
    1884
    1885 % --- Executes on button press in RenameClassButton.
    1886 function RenameClassButton_Callback(hObject, eventdata, handles)
    1887 % hObject    handle to RenameClassButton (see GCBO)
    1888 % eventdata  reserved - to be defined in a future version of MATLAB
    1889 % handles    structure with handles and user data (see GUIDATA)
    1890
    1891 class = handles.classes(handles.lastclass);
    1892 answer = inputdlg({'Class name'},'Edit class name',1,{class.name});
    1893
    1894 % check the answer
    1895 sizeanswer = size(answer);
    1896
    1897 secondanswer = '';
    1898
    1899 if sizeanswer(1)
    1900     if not(strcmp(class.name,answer{1}))
    1901         classnexists = doesclassexist(answer{1},handles.classes);
    1902         if classnexists
    1903             secondanswer = questdlg('Class name already exists. Do you want to merge the two classes.')
    1904         end
    1905         if strcmp(secondanswer,'Yes') || strcmp(secondanswer,'')
    1906             segments = rename_segments(handles.segments,class.name,answer{1});
    1907             class.name = answer{1};
    1908             cindex = handles.lastclass;
    1909             handles.classes(cindex) = class;
    1910             handles.segments = segments;
    1911
    1912             if strcmp(secondanswer,'Yes') % functionality for merging two classes
    1913                 handles.classes(classnexists).nmembers = handles.classes(classnexists).nmembers + handles.classes(cindex).nmembers;
    1914                 handles.classes = [handles.classes(1:(cindex-1)) handles.classes((cindex+1):handles.nclasses)];
    1915                 handles.nclasses = handles.nclasses - 1;
    1916                 class.nmembers = handles.classes(classnexists).nmembers; % this is parasitic code
    1917             end
    1918         end
    1919         handles = configureclassmembers(handles,class.name);
    1920         set_status(handles, ['Viewing ' num2str(class.nmembers),' members of ' class.name]);
    1921     end
    1922 end
    1923 guidata(gcbo,handles);
    1924
    1925
    1926 function spectras = subsamplespectra(spectra,lowerfreq,upperfreq,freqrange)
    1927 % Returns a subsampled frequency of the spectra
    1928
    1929 freqsamples = length(spectra(:,1));
    1930 freqratio = freqsamples / (freqrange(2) - freqrange(1));
    1931
    1932 lowerfreqsamp = round(lowerfreq * freqratio) + 1;
    1933 upperfreqsamp = round(upperfreq * freqratio) + 1;
    1934
    1935 if lowerfreqsamp < 1 % make sure we are not out of range
    1936     lowerfreqsamp = 1;
    1937 end
    1938
    1939 if upperfreq > freqsamples
    1940     upperfeqsamp = freqsamples;
    1941 end
    1942
    1943 spectras = spectra(lowerfreqsamp:upperfreqsamp,:);
    1944
    1945 function handles = generate_subsamples_icons(handles)
    1946 segments = handles.segments;
    1947 IconListf = {};
    1948 hw = waitbar(0,'Zooming spectra. . .');
    1949 for i = 1:handles.nsegments
    1950     load('-mat',segments(i).specfilename);
    1951     Ssub = subsamplespectra(S,handles.lowerfreq,handles.upperfreq,handles.fpass);
    1952     IconListf{i} = iconify_spec(Ssub,handles.ispecheight);
    1953     waitbar(i/handles.nsegments);
    1954 end
    1955 close(hw);
    1956 handles.IconListf = IconListf;
    1957
    1958
    1959 function handles = ZoomSpectra(handles,status)
    1960     if strcmp(status,'Zoom in')
    1961         if (length(handles.IconListf) == 0) || (handles.rezoom)
    1962             handles = generate_subsamples_icons(handles);
    1963             handles.rezoom = logical(0);
    1964         end
    1965         handles.FullIconList = handles.IconList;
    1966         set(handles.ZoomButton,'String','Zoom out');
    1967         handles.IconList = handles.IconListf;
    1968     elseif strcmp(status,'Zoom out');
    1969
    1970         if handles.rezoom
    1971             handles = generate_subsamples_icons(handles);
    1972             handles.rezoom = logical(0);
    1973             set(handles.ZoomButton,'String','Zoom out');
    1974             handles.IconList = handles.IconListf;
    1975         else
    1976             handles.IconList = handles.FullIconList;
    1977             set(handles.ZoomButton,'String','Zoom in');
    1978         end
    1979     end
    1980
    1981     for j = 1:handles.nclasses % switch over class icons
    1982         handles.classes(j).iconS = handles.IconList{handles.classes(j).index};
    1983     end
    1984
    1985     nimages = length(handles.mapindex);
    1986
    1987     % this is kind of ugly
    1988     if not(strcmp(handles.mode,'class-view')) && not(strcmp(handles.mode,'comparison')) % update images
    1989         for i = 1:nimages
    1990             handles.image_list{i} = handles.IconList{handles.mapindex(i)};
    1991         end
    1992     elseif strcmp(handles.mode,'comparison')
    1993         handles.image_list{1} = handles.IconList{handles.NextIndex};
    1994         handles.image_list{2} = handles.IconList{handles.classes(handles.lastclass).index};
    1995     else
    1996         for i = 1:nimages
    1997             handles.image_list{i} = handles.IconList{handles.classes(handles.mapindex(i)).index};
    1998         end
    1999     end
    2000
    2001     handles=get_and_plot(handles,handles.segments(handles.NextIndex));
    2002     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    2003
    2004
    2005
    2006 % --- Executes on button press in ZoomButton.
    2007 function ZoomButton_Callback(hObject, eventdata, handles)
    2008 % hObject    handle to ZoomButton (see GCBO)
    2009 % eventdata  reserved - to be defined in a future version of MATLAB
    2010 % handles    structure with handles and user data (see GUIDATA)
    2011
    2012 status = get(handles.ZoomButton,'String');
    2013
    2014 handles = ZoomSpectra(handles,status);
    2015
    2016 guidata(gcbo,handles);
    2017
    2018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2019 % Functions for computing class statistics      %
    2020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2021
    2022 function [meanl sdl] = stat_lengths(handles)
    2023 lengthsarray = [];
    2024 for i = 1:length(handles.mapindex)
    2025     lengthsarray(i) = handles.segments(i).end - handles.segments(i).start;
    2026 end
    2027 meanl = mean(lengthsarray);
    2028 sdl = sd(lengthsarray);
    2029
    2030
    2031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2032 % Functions for quick classify mode                %
    2033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2034
    2035 function handles = quick_mode_exit(handles)
    2036     set(handles.SkipButton,'Visible','off');
    2037     set(handles.UndoButton,'Visible','off');
    2038     set(handles.NewQuickButton,'Visible','off');
    2039
    2040     set(handles.ViewText,'Visible','on');
    2041     set(handles.ModePopupMenu,'Visible','on');
    2042     set(handles.SegInfoText,'Visible','on');
    2043
    2044     set(handles.ClassifyButton,'Enable','on');
    2045     set(handles.RemoveClassButton,'Enable','on');
    2046     set(handles.RemoveClassButton,'Visible','on');
    2047     set(handles.CompareToggleButton,'Enable','on');
    2048     set(handles.AutoClassifyButton,'Enable','on');
    2049     set(handles.SortPopupMenu,'Visible','off');
    2050     set(handles.ModePopupMenu,'Value',3);
    2051
    2052     handles.submode='select';
    2053
    2054     set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes']);
    2055
    2056     setnavigationbuttons(handles);
    2057
    2058
    2059 % --- Executes on button press in QuickModeButton.
    2060 function QuickModeButton_Callback(hObject, eventdata, handles)
    2061 % hObject    handle to QuickModeButton (see GCBO)
    2062 % eventdata  reserved - to be defined in a future version of MATLAB
    2063 % handles    structure with handles and user data (see GUIDATA)
    2064
    2065 if not(handles.quickmode) % turn on quick mode
    2066
    2067     handles.quickmode = 1;
    2068
    2069     % Turn off top header
    2070     set(handles.ViewText,'Visible','off');
    2071     set(handles.ModePopupMenu,'Visible','off');
    2072     set(handles.SegInfoText,'Visible','off');
    2073
    2074     % Make visible quick mode buttons
    2075     set(handles.SkipButton,'Visible','on');
    2076     set(handles.SkipButton,'Enable','on');
    2077     set(handles.UndoButton,'Visible','on');
    2078     set(handles.UndoButton,'Enable','on');
    2079     set(handles.NewQuickButton,'Visible','on');
    2080     set(handles.NewQuickButton,'Visible','on');
    2081
    2082     set(handles.SortPopupMenu,'Visible','on');
    2083
    2084     % Disable regular mode functions
    2085     set(handles.RemoveClassButton,'Visible','off');
    2086     set(handles.NextClassButton,'Visible','off');
    2087     set(handles.NextSpectraButton,'Enable','off');
    2088     set(handles.PreviousSpectraButton,'Enable','off');
    2089     set(handles.ClassifyButton,'Enable','off');
    2090     set(handles.TypifyClassButton,'Visible','off');
    2091     set(handles.RenameClassButton,'Visible','off');
    2092     set(handles.CompareToggleButton,'Enable','off');
    2093     set(handles.AutoClassifyButton,'Enable','off');
    2094
    2095     % Will need to disable buttons underneath classified axes
    2096     if not(strcmp(handles.segments(handles.NextIndex).class,''))
    2097         handles = jump_to_unclassified(handles);
    2098         handles.lastsegment = handles.NextIndex;
    2099     end
    2100
    2101     if handles.nclasses >= 1
    2102         handles = configureclassview(handles,'select-class');
    2103         handles.mode = 'class-view';
    2104         handles.submode = 'select-class';
    2105     else % empty axes
    2106         handles = blankaxes(handles);
    2107         handles.mode = 'class-view';
    2108         handles.submode = 'xxx';
    2109     end
    2110
    2111
    2112 else
    2113     handles.quickmode = 0;
    2114     handles = quick_mode_exit(handles);
    2115
    2116     % Will need to intellegently enable buttons underneath classified axes
    2117 end
    2118
    2119 guidata(gcbo,handles);
    2120
    2121 function handles=jump_to_unclassified(handles)
    2122 % Jumps to the next unclassified segment
    2123 currindex = handles.NextIndex;
    2124 i = currindex;
    2125 while (mod(i,handles.nsegments)+1 ~= currindex) && not(strcmp(handles.segments(mod(i,handles.nsegments) + 1).class,''))
    2126     i = i + 1;
    2127 end
    2128
    2129 if not(mod(i,handles.nsegments)+1 == currindex) % there are some unclassified segments
    2130     handles.NextIndex = mod(i,handles.nsegments) + 1;
    2131     handles=ConfigureClassSegment(handles);
    2132     handles=ConfigureSpecPlot(handles);
    2133     set(handles.ClassifyButton,'Enable','off');
    2134 end
    2135 %get(handles.QuickModeButton,'Value')
    2136 handles.lastsegment = currindex;
    2137
    2138 % --- Executes on button press in SkipButton.
    2139 function SkipButton_Callback(hObject, eventdata, handles)
    2140 % hObject    handle to SkipButton (see GCBO)
    2141 % eventdata  reserved - to be defined in a future version of MATLAB
    2142 % handles    structure with handles and user data (see GUIDATA)
    2143 handles = jump_to_unclassified(handles);
    2144
    2145 if handles.lastsegment == handles.NextIndex % no more unclassified segments
    2146     handles = quick_mode_exit(handles);
    2147     set(handles.QuickModeButton,'Value',0);
    2148     handles.quickmode = not(handles.quickmode);
    2149 end
    2150
    2151 handles = configureclassview(handles,'select-class');
    2152
    2153 guidata(gcbo,handles);
    2154 % --- Executes on button press in UndoButton.
    2155 function UndoButton_Callback(hObject, eventdata, handles)
    2156 % hObject    handle to UndoButton (see GCBO)
    2157 % eventdata  reserved - to be defined in a future version of MATLAB
    2158 % handles    structure with handles and user data (see GUIDATA)
    2159
    2160 handles.NextIndex = handles.lastsegment;
    2161 handles=ConfigureClassSegment(handles);
    2162 handles=ConfigureSpecPlot(handles);
    2163
    2164 handles = quick_mode_exit(handles);
    2165
    2166 set(handles.QuickModeButton,'Value',0);
    2167 handles.quickmode = not(handles.quickmode);
    2168
    2169 guidata(gcbo,handles);
    2170
    2171 % --- Executes on button press in NewQuickButton.
    2172 function NewQuickButton_Callback(hObject, eventdata, handles)
    2173 % hObject    handle to NewQuickButton (see GCBO)
    2174 % eventdata  reserved - to be defined in a future version of MATLAB
    2175 % handles    structure with handles and user data (see GUIDATA)
    2176
    2177 handles = add_new_class(handles,handles.segments(handles.NextIndex));
    2178 handles.segments(handles.NextIndex).class = handles.classes(handles.nclasses).name;
    2179
    2180 set(handles.ClassifyButton,'Enable','off');
    2181
    2182 handles = jump_to_unclassified(handles);
    2183 handles = configureclassview(handles,'select-class');
    2184
    2185 if handles.lastsegment == handles.NextIndex % no more unclassified segments
    2186     handles = quick_mode_exit(handles)
    2187     set(handles.QuickModeButton,'Value',0);
    2188     handles.quickmode = not(handles.quickmode);
    2189 end
    2190
    2191 guidata(gcbo,handles);
    2192
    2193
    2194
    2195 % --- Executes on button press in CompareToggleButton.
    2196 function CompareToggleButton_Callback(hObject, eventdata, handles)
    2197 % hObject    handle to CompareToggleButton (see GCBO)
    2198 % eventdata  reserved - to be defined in a future version of MATLAB
    2199 % handles    structure with handles and user data (see GUIDATA)
    2200
    2201 % Hint: get(hObject,'Value') returns toggle state of CompareToggleButton
    2202
    2203 state = get(hObject,'Value');
    2204
    2205 if handles.nclasses > 0
    2206
    2207  if state % enter compare mode
    2208     handles.mode = 'class-view';
    2209     set(handles.RemoveClassButton,'Enable','off');
    2210     set(handles.RenameClassButton,'Visible','off');
    2211     set(handles.NextClassButton,'Visible','off');
    2212     set(handles.ModePopupMenu,'Enable','off');
    2213     set(handles.ClassifyButton,'Enable','off');
    2214     set(handles.QuickModeButton,'Enable','off');
    2215     set_status(handles,'Select a class to compare segment against');
    2216     set(handles.NextSpectraButton,'Enable','off');
    2217     set(handles.PreviousSpectraButton,'Enable','off');
    2218     set(handles.TypifyClassButton, 'Visible', 'off');
    2219     set(handles.AutoClassifyButton,'Enable','off');
    2220
    2221     handles = configureclassview(handles,'compare');
    2222  else
    2223     if strcmp(handles.mode,'comparison') % go back to the class view
    2224         set(hObject,'Value',1);
    2225         handles.startx = 1; % if you have been scrolling reset to defaults
    2226         handles.endx = handles.classified_width;
    2227
    2228         set(handles.SliderClassified, 'Value',0);
    2229         handles = configureclassview(handles,'compare');
    2230         handles.mode = 'class-view';
    2231         set_status(handles,'Select a class to compare segment against');
    2232     elseif strcmp(handles.mode,'class-view') % exit the compare mode entirely
    2233         set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
    2234         set(handles.ModePopupMenu,'Enable','on');
    2235         set(handles.QuickModeButton,'Enable','on');
    2236         setnavigationbuttons(handles);
    2237         SetModePopupMenu(handles,'class view');
    2238         set(handles.RemoveClassButton,'Enable','on');
    2239         set(handles.RemoveClassButton,'Visible','on');
    2240         set(handles.ClassifyButton,'Enable','on');
    2241         set(handles.AutoClassifyButton,'Enable','on');
    2242         handles.submode = 'select';
    2243     end
    2244  end
    2245
    2246 else
    2247     set(hObject,'Value',0);
    2248 end
    2249 guidata(hObject, handles);
    2250
    2251 function handles = recompute_classifiedaxes(handles)
    2252 % Recomputes the width and height based on a new size for the classified
    2253 % axes
    2254
    2255     classaxpos=get(handles.ClassifiedAxes,'Position');
    2256
    2257     set(handles.SliderClassified,'Value',0);
    2258
    2259     handles.startx = 1;
    2260
    2261     handles.classified_width = round(handles.classified_width_density * classaxpos(3));
    2262     handles.classified_height = round(handles.classified_height_density * classaxpos(4));
    2263
    2264     oldpos = handles.startpage;
    2265     handles = reposition_images(handles, handles.image_list); % try to keep rows matched
    2266
    2267     cnrow = which_row(handles.positions,oldpos);
    2268     for i = 1:(cnrow-1)
    2269            handles = row_forward(handles);
    2270     end
    2271
    2272     handles.cpositions =  get_curr_position(handles);
    2273     handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
    2274
    2275 function reposy(guielement,deltay)
    2276     oldpos = get(guielement,'Position');
    2277     set(guielement,'Position',[oldpos(1), oldpos(2) + deltay, oldpos(3), oldpos(4)]);
    2278
    2279 function reposelementsy(handles,deltay)
    2280     reposy(handles.PrecomputeButton,deltay);
    2281     reposy(handles.DirectoryEditBox,deltay);
    2282     reposy(handles.LoadDirectoryButton,deltay);
    2283     reposy(handles.SaveButton,deltay);
    2284     reposy(handles.ConfigureButton,deltay);
    2285     reposy(handles.ViewText,deltay);
    2286     reposy(handles.ModePopupMenu,deltay);
    2287     reposy(handles.SegInfoText,deltay);
    2288     reposy(handles.ToClassifyPanel,deltay);
    2289     reposy(handles.NewQuickButton,deltay);
    2290     reposy(handles.UndoButton,deltay);
    2291     reposy(handles.SkipButton,deltay);
    2292     reposy(handles.SortText,deltay);
    2293     reposy(handles.SortPopupMenu,deltay);
    2294     reposy(handles.NextClassButton,deltay);
    2295
    2296 function ResizeFcn(h, eventdata, handles, varargin)
    2297
    2298     handles = guidata(gcbo);
    2299
    2300     originalsize = handles.originalsize;
    2301     newsize = get(h,'Position');
    2302     classaxpos = get(handles.ClassifiedAxes,'Position');
    2303
    2304     if handles.originalsize(3) > newsize(3) % if form has smaller width bounce back
    2305         newsize(3) = originalsize(3);
    2306         classaxpos(3) = handles.originalaxessize(3);
    2307
    2308         sliderpos = get(handles.SliderClassified,'Position'); % Update the slider
    2309         sliderpos(3) = classaxpos(3);
    2310         set(handles.SliderClassified,'Position',sliderpos);
    2311
    2312     else % form is larger
    2313         deltax = newsize(3) - handles.prevsize(3);
    2314         classaxpos(3) = classaxpos(3) + deltax; % update width of the axes
    2315
    2316         sliderpos = get(handles.SliderClassified,'Position'); % Update the slider
    2317         sliderpos(3) = sliderpos(3) + deltax;
    2318         set(handles.SliderClassified,'Position',sliderpos);
    2319
    2320     end
    2321
    2322     if originalsize(4) > newsize(4) % if form has a smaller height bounce back
    2323         newsize(2) = newsize(2) + newsize(4) - originalsize(4);
    2324
    2325         deltay =  originalsize(4) - handles.prevsize(4);
    2326         newsize(4) = originalsize(4);
    2327         classaxpos(4) = classaxpos(4) + newsize(4) - handles.prevsize(4);
    2328         reposelementsy(handles,deltay);
    2329
    2330     else % form is larger we need to reposition elements
    2331         deltay = newsize(4) - handles.prevsize(4);
    2332         reposelementsy(handles,deltay);
    2333         classaxpos(4) = classaxpos(4) + newsize(4) - handles.prevsize(4);
    2334     end
    2335
    2336     set(h,'Position',newsize);
    2337     set(handles.ClassifiedAxes,'Position',classaxpos);
    2338
    2339     if handles.fixed || handles.blank % allow fixed resizing
    2340         % do nothing except update the density measurements
    2341         handles.classified_width_density = handles.classified_width / classaxpos(3);
    2342         handles.classified_height_density = handles.classified_height / classaxpos(4);
    2343     else % reposition images
    2344         handles = recompute_classifiedaxes(handles);
    2345     end
    2346
    2347     handles.prevsize = newsize;
    2348
    2349     guidata(gcbo,handles);
    2350
    2351 function truth = truthrange(range)
    2352     truth = range(1) && range (2);
    2353
    2354 % --- Executes on button press in ConfigureButton.
    2355 function ConfigureButton_Callback(hObject, eventdata, handles)
    2356 % hObject    handle to ConfigureButton (see GCBO)
    2357 % eventdata  reserved - to be defined in a future version of MATLAB
    2358 % handlenb  vcccs    structure with handles and user data (see GUIDATA)
    2359
    2360
    2361     configs = configure_classify(handles.lowerfreq,handles.upperfreq,handles.classified_height,handles.classified_width,handles.Fs,handles.movingwin,handles.tapers,handles.fpass,handles.fixed);
    2362     if not(isempty(configs) || length(configs) == 1)  % if okay is pressed
    2363         lowerfreq= configs{1};
    2364         upperfreq= configs{2};
    2365         classified_height= configs{3};
    2366         classified_width= configs{4};
    2367         Fs=configs{5};
    2368         movingwin= configs{6};
    2369         tapers= configs{7};
    2370         fpass = configs{8};
    2371
    2372         rezoom = 0;
    2373
    2374         if not(handles.lowerfreq == lowerfreq)
    2375             handles.lowerfreq = lowerfreq;
    2376             rezoom = 1;
    2377         end
    2378
    2379         if not(handles.upperfreq==upperfreq)
    2380             handles.upperfreq=upperfreq;
    2381             rezoom=1;
    2382         end
    2383
    2384         redraw = 0;
    2385         if not(handles.classified_height==classified_height)
    2386             handles.classified_height=classified_height;
    2387             redraw = 1;
    2388         end
    2389
    2390         if not(handles.classified_width==classified_width)
    2391             handles.classified_width=classified_height;
    2392             redraw = 1;
    2393         end
    2394
    2395         recompute = 0; % check to see if the spectra needs to be recomputed
    2396
    2397         if not(handles.Fs==Fs)
    2398             handles.Fs = Fs;
    2399             recompute = 1;
    2400         end
    2401
    2402         if not(truthrange(handles.movingwin == movingwin))
    2403             handles.movingwin = movingwin;
    2404             recompute = 1;
    2405         end
    2406
    2407         if not(truthrange(handles.tapers==tapers))
    2408             handles.tapers=tapers;
    2409             recompute = 1;
    2410         end
    2411
    2412         if not(truthrange(handles.fpass==fpass))
    2413             handles.fpass=fpass;
    2414             recompute = 1;
    2415         end
    2416
    2417
    2418         if recompute % The spectra need to be recomputed
    2419             status = questdlg('Recompute spectra with changed parameters');
    2420             if not(isempty(status))
    2421                 if strcmp(status,'Yes')
    2422                      handles = precompute_AllSpectra(handles);
    2423                      save_configuration(handles,handles.configfile); % Save configuration no matter what
    2424
    2425                      handles=ConfigureSpecPlot(handles); % automatically force into browse mode
    2426                      set(handles.RemoveClassButton,'Visible','off');
    2427                      set(handles.TypifyClassButton, 'Visible', 'off');
    2428                      set(handles.NextClassButton,'Visible','off');
    2429
    2430                      handles=BrowseDirectory(handles);
    2431                      set(handles.ModePopupMenu,'Value',1);
    2432
    2433                      if handles.nclasses >= 1 % sync changes to the classview
    2434                         for j = 1:handles.nclasses
    2435                             handles.classes(j).iconS = handles.IconList{handles.classes(j).index};
    2436                         end
    2437                      end
    2438
    2439                      set(handles.RemoveClassButton,'Visible','off'); % update buttons
    2440                      set(handles.TypifyClassButton, 'Visible', 'off');
    2441                      set(handles.NextClassButton,'Visible','off');
    2442
    2443                      redraw = logical(1);
    2444                 end
    2445             end
    2446         end
    2447
    2448         if rezoom
    2449             if strcmp(get(handles.ZoomButton,'String'),'Zoom out')
    2450                 handles.rezoom = logical(1);
    2451                 handles = ZoomSpectra(handles,'Zoom out');
    2452             else
    2453                 handles.rezoom = logical(1); % Otherwise wait to user hits the rezoom button
    2454             end
    2455         end
    2456
    2457         if not(handles.configschanged) % handles the case were the configurations were changed already
    2458             if not(recompute)
    2459                 handles.configschanged = logical(1);
    2460             end
    2461         end
    2462
    2463         if redraw % Redraw the axes
    2464             classaxpos = get(handles.ClassifiedAxes,'Position');
    2465             handles.classified_width_density = handles.classified_width / classaxpos(3);
    2466             handles.classified_height_density = handles.classified_height / classaxpos(4);
    2467             handles = recompute_classifiedaxes(handles);
    2468          end
    2469
    2470         handles.fixed = configs{9};
    2471
    2472 end
    2473 guidata(gcbo,handles);
    2474
    2475 function status = save_configuration(handles,filename)
    2476
    2477     Fs = handles.Fs;
    2478     movingwin = handles.movingwin;
    2479     tapers = handles.tapers;
    2480     fpass = handles.fpass;
    2481
    2482     try
    2483         save(filename,'Fs','movingwin','tapers','fpass','-mat');
    2484     catch
    2485         status = 1;
    2486     end
    2487
    2488 function handles = load_configuration(handles,filename)
    2489     try
    2490         load('-mat',filename)
    2491         if handles.Fs == Fs || handles.movingwin == movingwin || handles.tapers == tapers || handles.fpass == fpass
    2492             handles.configshavechanged = logical(1);
    2493         end
    2494
    2495         handles.Fs = Fs;
    2496         handles.movingwin = movingwin;
    2497         handles.tapers = tapers;
    2498         handles.fpass = fpass;
    2499     catch
    2500         handles = handles;
    2501     end
    2502
    2503
    2504 % --- Executes on button press in NextClassButton.
    2505 function NextClassButton_Callback(hObject, eventdata, handles)
    2506 % hObject    handle to NextClassButton (see GCBO)
    2507 % eventdata  reserved - to be defined in a future version of MATLAB
    2508 % handles    structure with handles and user data (see GUIDATA)
    2509
    2510 handles.lastclass = handles.lastclass + 1;
    2511
    2512 if handles.lastclass > handles.nclasses
    2513     handles.lastclass = 1;
    2514 end
    2515
    2516 class = handles.classes(handles.lastclass);
    2517 handles = configureclassmembers(handles,class.name);
    2518 set_status(handles,['Viewing ' num2str(length(handles.mapindex)) ' members of ' class.name]);
    2519 handles.mode = 'class-members';
    2520 handles.submode = 'select';
    2521
    2522 guidata(gcbo,handles);
    2523
    2524 function handles = features_segments(handles)
    2525
    2526 h=waitbar(0,'Computing Data Features. . . ');
    2527 for i = 1:handles.nsegments
    2528     startf = handles.segments(i).start;
    2529     endf = handles.segments(i).end;
    2530     cepestral = cepsfromspectra(handles.segments(i).specfilename,handles.ncepestral);
    2531
    2532     % Below shows how additional data features can be included in the
    2533     % exporting and classifying using the software
    2534
    2535     % The commented code shows how the wave file can be read in to
    2536     % calculate additional data features
    2537
    2538     %     segment = handles.segments(i);
    2539     %     data = wavread(segment.wavfile,round(handles.Fs * [segment.start segment.end]));
    2540
    2541     waitbar(i/handles.nsegments);
    2542
    2543     handles.segments(i).features = cepestral';
    2544
    2545     % Three additional data features can be added for example as following
    2546     %
    2547     % additional_features = compute_features(data,3);
    2548     % handles.nfeatures = handles.nfeatures + 3;
    2549     % handles.segments(i).features = [handles.segments(i).features additional_features'];
    2550 end
    2551 close(h);
    2552
    2553 function coefs = cepsfromspectra(specfilename,ncepestral)
    2554   load('-mat',specfilename);
    2555   sbase = (mean(min(exp(Spre))) + mean(min(exp(Spost)))) / 2; % might not be a good
    2556                                            % baseline because of
    2557                                            % the intensity of the
    2558                                            % sound around the syllable that
    2559                                            % is why I took the average
    2560                                            % minimum value
    2561
    2562   %Sdiff = S - sbase;
    2563
    2564   Sdiff = exp(S) - sbase; % arithmetic average
    2565   spectra = log(mean(Sdiff')); % average across time to generate spectra
    2566
    2567   %spectra=mean(Sdiff');
    2568
    2569   cepstrum = real(ifft(spectra));
    2570
    2571   % alternative methods for computing the cepstrum
    2572   %real(fft(hamming(length(spectra) .* spectra )));
    2573   %cepstrum = real(fft(spectra))
    2574
    2575   coefs = cepstrum(1:ncepestral); % this I understand is the
    2576                                    % correct way
    2577
    2578 function classifymatrix = generate_classify_mat(handles)
    2579     classifymatrix = zeros(handles.nsegments,handles.nfeatures+1);
    2580     for i = 1:handles.nsegments
    2581         seglength = handles.segments(i).end - handles.segments(i).start;
    2582         classifymatrix(i,1:1+handles.nfeatures) = [seglength handles.segments(i).features(1:handles.nfeatures)'];
    2583     end
    2584 ;
    2585
    2586 function handles = generate_classes_auto(handles,classification)
    2587     nclasses = length(unique(classification));
    2588     classesfound = zeros(nclasses,1); % used to check which classes exist
    2589     handles.classes = [];
    2590     handles.nclasses = 0;
    2591     j = 1;
    2592     for i = 1:handles.nsegments
    2593         if classification(i) == 0 % segment has not been classified
    2594             handles.segments(i).class = '';
    2595         else
    2596             if isempty(classesfound(find(classesfound == classification(i)))) % a new class is found
    2597                 class.specfilename = handles.segments(i).specfilename;
    2598                 class.name = newclassname(handles);
    2599                 class.index = i;
    2600                 class.length = handles.segments(i).end - handles.segments(i).start;
    2601                 class.iconS = handles.IconList{i};
    2602                 class.nmembers = 1;
    2603                 handles.segments(i).class = class.name;
    2604                 handles.classes = [handles.classes class];
    2605                 classesfound(j) = classification(i);
    2606                 j = j + 1;
    2607                 handles.nclasses = handles.nclasses + 1;
    2608             else % segment belongs to a class that already exists
    2609                 classindex = find(classification(i) == classesfound);
    2610                 handles.segments(i).class = handles.classes(classindex).name;
    2611                 handles.classes(classindex).nmembers = handles.classes(classindex).nmembers + 1;
    2612             end
    2613         end
    2614     end
    2615    ;
    2616
    2617 % --- Executes on button press in AutoClassifyButton.
    2618 function AutoClassifyButton_Callback(hObject, eventdata, handles)
    2619 % hObject    handle to AutoClassifyButton (see GCBO)
    2620 % eventdata  reserved - to be defined in a future version of MATLAB
    2621 % handles    structure with handles and user data (see GUIDATA)
    2622
    2623 if length(handles.segments(1).features) == 0;  % compute cepestral coefficients if not computed before
    2624     handles = features_segments(handles);
    2625 end
    2626
    2627 matrix2classify = generate_classify_mat(handles);
    2628
    2629 classification = auto_classify(matrix2classify,handles.nfeatures);
    2630
    2631 if length(classification) > 1  %&& not(classification == 0)
    2632     if not(isempty(handles.classes))
    2633         answer = questdlg('A classification already exists. Do you want to replace the current classification?');
    2634         if strcmp(answer,'Yes')
    2635             handles = generate_classes_auto(handles,classification);
    2636         end
    2637     else
    2638         handles = generate_classes_auto(handles,classification);
    2639
    2640     end
    2641
    2642     handles=configureclassview(handles,'select');
    2643     set(handles.ClassifyButton,'String','Declassify'); % all classes are now classified
    2644     set(handles.RemoveClassButton,'Visible','on');
    2645     set(handles.RemoveClassButton,'Enable','on');
    2646     set(handles.CompareToggleButton,'Visible','on');
    2647     set(handles.CompareToggleButton,'Enable','on');
    2648     set(handles.TypifyClassButton, 'Visible', 'off');
    2649     set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes'])
    2650 %
    2651 %     set(handles.ModePopupMenu,'Value',3);
    2652 %
    2653 %     ModePopupMenu_Callback(handles.ModePopupMenu,eventdata, handles);
    2654 %     handles.mode = 'class-view';
    2655 %     handles.submode = 'select';
    2656
    2657 end
    2658 guidata(gcbo,handles);
    2659
    2660
    2661 % --------------------------------------------------------------------
    2662 function FileMenu_Callback(hObject, eventdata, handles)
    2663 % hObject    handle to FileMenu (see GCBO)
    2664 % eventdata  reserved - to be defined in a future version of MATLAB
    2665 % handles    structure with handles and user data (see GUIDATA)
    2666
    2667
    2668 % --------------------------------------------------------------------
    2669 function SaveItem_Callback(hObject, eventdata, handles)
    2670 % hObject    handle to SaveItem (see GCBO)
    2671 % eventdata  reserved - to be defined in a future version of MATLAB
    2672 % handles    structure with handles and user data (see GUIDATA)
    2673
    2674 SaveButton_Callback(hObject, eventdata, handles)
    2675
    2676 % --------------------------------------------------------------------
    2677 function LoadItem_Callback(hObject, eventdata, handles)
    2678 % hObject    handle to LoadItem (see GCBO)
    2679 % eventdata  reserved - to be defined in a future version of MATLAB
    2680 % handles    structure with handles and user data (see GUIDATA)
    2681
    2682 PrecomputeButton_Callback(hObject, eventdata, handles)
    2683
    2684 %guidata(gcbo,handles)
    2685
    2686 % --------------------------------------------------------------------
    2687 function HelpMenu_Callback(hObject, eventdata, handles)
    2688 % hObject    handle to HelpMenu (see GCBO)
    2689 % eventdata  reserved - to be defined in a future version of MATLAB
    2690 % handles    structure with handles and user data (see GUIDATA)
    2691
    2692
    2693 % --------------------------------------------------------------------
    2694 function HelpItem_Callback(hObject, eventdata, handles)
    2695 % hObject    handle to HelpItem (see GCBO)
    2696 % eventdata  reserved - to be defined in a future version of MATLAB
    2697 % handles    structure with handles and user data (see GUIDATA)
    2698
    2699 web('classify_spectra_help.html');
    2700
    2701 % --------------------------------------------------------------------
    2702 function AboutItem_Callback(hObject, eventdata, handles)
    2703 % hObject    handle to AboutItem (see GCBO)
    2704 % eventdata  reserved - to be defined in a future version of MATLAB
    2705 % handles    structure with handles and user data (see GUIDATA)
    2706
    2707 msgbox('Classify_spectra (version 0.2) is being developed by the Mitra Lab at the Cold Spring Harbor Laboratory.','About classify_spectra');
    2708
    2709
    2710 % --------------------------------------------------------------------
    2711 function ConfigureItem_Callback(hObject, eventdata, handles)
    2712 % hObject    handle to ConfigureItem (see GCBO)
    2713 % eventdata  reserved - to be defined in a future version of MATLAB
    2714 % handles    structure with handles and user data (see GUIDATA)
    2715
    2716 ConfigureButton_Callback(hObject, eventdata, handles)
    2717
    2718 function coefs = cepcoefs(data,p)
    2719 % Computes the cepstral coefficients from the data returns p coefficients
    2720 coefs = [];
    2721 if p > 0
    2722     y = fft(hamming(length(data)) .* data);
    2723     coefs = aryule(ifft(log(abs(y))),p);
    2724 end
    2725
    2726 function generate_output(handles,absolutetime,filename);
    2727
    2728     filebasetosave = filename(1:length(filename)-4);
    2729
    2730     matrixoutput = cell(handles.nsegments,1);
    2731
    2732     for i = 1:handles.nsegments
    2733         segment = handles.segments(i);
    2734
    2735         if absolutetime
    2736             dstr = regexp(segment.wavfile,'[0-9]+\-[0-9]+\-[0-9]+','match');
    2737             dstr = dstr{1}; % take first match only
    2738             tstr = regexp(segment.wavfile,'[0-9][0-9][0-9][0-9][0-9][0-9]','match');
    2739             tstr = tstr{1};
    2740             tstr = [tstr(1:2) ':' tstr(3:4) ':' tstr(5:6)];
    2741             segmentstart = datenum([dstr ' ' tstr]) + segment.start;
    2742             segmentstart = datevec(segmentstart);
    2743         else
    2744             segmentstart = segment.start;
    2745         end
    2746             matrixoutput{i} = {segment.wavfile,segment.class,segmentstart,segment.end - segment.start,segment.features};
    2747     end
    2748
    2749     save([filebasetosave '.mat'],'-mat','matrixoutput','-mat');
    2750
    2751     delimiter = '\t';
    2752     fp = fopen([filebasetosave '.txt'],'wt');
    2753
    2754     % Generate header for file
    2755
    2756     fprintf(fp,'filename');fprintf(fp,delimiter);
    2757     fprintf(fp,'class');fprintf(fp,delimiter);
    2758
    2759     if absolutetime
    2760         fprintf(fp,'year');fprintf(fp,delimiter);
    2761         fprintf(fp,'month');fprintf(fp,delimiter);
    2762         fprintf(fp,'day');fprintf(fp,delimiter);
    2763         fprintf(fp,'hour');fprintf(fp,delimiter);
    2764         fprintf(fp,'minute');fprintf(fp,delimiter);
    2765         fprintf(fp,'second');fprintf(fp,delimiter);
    2766     else
    2767         fprintf(fp,'start');fprintf(fp,delimiter);
    2768     end
    2769
    2770     fprintf(fp,'length');fprintf(fp,delimiter);
    2771
    2772     for i = 1:handles.nfeatures
    2773         fprintf(fp,['d' num2str(i)]);
    2774         if i < handles.nfeatures;
    2775             fprintf(fp,delimiter);
    2776         else
    2777             fprintf(fp,'\n');
    2778         end
    2779     end
    2780
    2781
    2782     % Generate main data
    2783
    2784     for i = 1:handles.nsegments
    2785         segment = handles.segments(i);
    2786         fprintf(fp,['"' segment.wavfile '"']);fprintf(fp,delimiter);
    2787         fprintf(fp,['"' segment.class '"']);fprintf(fp,delimiter);
    2788
    2789         if absolutetime
    2790             time = matrixoutput{i}{3};
    2791
    2792             fprintf(fp,num2str(time(1)));fprintf(fp,delimiter);
    2793             fprintf(fp,num2str(time(2)));fprintf(fp,delimiter);
    2794             fprintf(fp,num2str(time(3)));fprintf(fp,delimiter);
    2795             fprintf(fp,num2str(time(4)));fprintf(fp,delimiter);
    2796             fprintf(fp,num2str(time(5)));fprintf(fp,delimiter);
    2797             fprintf(fp,num2str(time(6)));
    2798
    2799         else
    2800             fprintf(fp,num2str(segment.start));
    2801         end
    2802
    2803         fprintf(fp,delimiter);
    2804         fprintf(fp,num2str(segment.end-segment.start));fprintf(fp,delimiter);
    2805
    2806         for j = 1:handles.nfeatures
    2807             fprintf(fp,num2str(segment.features(j)));
    2808             if j < handles.nfeatures % handle eol formatting
    2809                 fprintf(fp,delimiter);
    2810             else
    2811                 if i < handles.nsegments % handle eof formatting
    2812                     fprintf(fp,'\n');
    2813                 end
    2814             end
    2815         end
    2816     end
    2817     fclose(fp);
    2818 % --------------------------------------------------------------------
    2819 function ExportDataItem_Callback(hObject, eventdata, handles)
    2820 % hObject    handle to ExportDataItem (see GCBO)
    2821 % eventdata  reserved - to be defined in a future version of MATLAB
    2822 % handles    structure with handles and user data (see GUIDATA)
    2823
    2824 filename = uiputfile('*.txt','File to write exported data to');
    2825
    2826 if not(filename == 0)
    2827     if length(handles.segments(1).features) == 0
    2828         handles = features_segments(handles);
    2829     end
    2830     generate_output(handles,1,filename);
    2831 end
    2832
    2833
    2834 % --------------------------------------------------------------------
    2835 function CleanDirectoryItem_Callback(hObject, eventdata, handles)
    2836 % hObject    handle to CleanDirectoryItem (see GCBO)
    2837 % eventdata  reserved - to be defined in a future version of MATLAB
    2838 % handles    structure with handles and user data (see GUIDATA)
    2839
    2840 answer = questdlg('Clean the current directory. This will remove all files generated by classify_spectra including the file which includes the classification');
    2841 if strcmp(answer,'Yes');
    2842     specfiles = dir('*.spec');
    2843
    2844     for i = 1:length(specfiles)
    2845         delete(specfiles(i).name);
    2846     end
    2847
    2848
    2849     if exist('class_spec.conf')
    2850         delete('class_spec.conf');
    2851     end
    2852
    2853     if exist([handles.baseclassname '.dat'])
    2854         delete([handles.baseclassname '.dat']);
    2855     end
    2856
    2857
    2858 end