0001 function varargout = classify_spectra(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
0046
0047
0048 function classify_spectra_OpeningFcn(hObject, eventdata, handles, varargin)
0049
0050
0051
0052
0053
0054
0055
0056 handles.output = hObject;
0057
0058
0059 handles.recompute = logical(1);
0060 handles.cwavfile = '';
0061
0062 handles.directory = pwd;
0063
0064 handles.Fs = 44100;
0065 handles.movingwin=[0.01 0.002];
0066 handles.tapers=[3 5];
0067 handles.pad=1;
0068 handles.fpass=[0 20000];
0069
0070 handles.nsegments = 0;
0071 handles.NextIndex = 1;
0072 handles.maxseglength = 0;
0073
0074
0075
0076 handles.classified_height = 560 ;
0077 handles.classified_width = 450;
0078
0079
0080
0081 handles.plotmode = 'spectra';
0082
0083
0084 handles.plotmodes = {'spectra' 'waveform' 'spectra_dt' 'spectra_df' };
0085
0086 handles.plotmodevalue = 1;
0087
0088
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;
0095 handles.ismaxwidth = SmallAxes_width(handles);
0096 handles.specpad = 0.02;
0097
0098 handles.xspacer = 5;
0099 handles.yspacer = 10;
0100
0101 handles.xpsacer_density = handles.xspacer / classaxpos(3);
0102 handles.ypsacer_density = handles.yspacer / classaxpos(4);
0103
0104 handles.image_list = {};
0105 handles.positions = [];
0106 handles.images_dim = [];
0107
0108 handles.mapindex = [];
0109
0110 handles.nimages = 0;
0111 handles.number_rows = floor(handles.classified_height/(handles.yspacer + handles.ispecheight));
0112
0113 handles.cnrows = 0;
0114
0115 handles.startpage = 1;
0116 handles.endpage = 1;
0117
0118 handles.startx = 1;
0119 handles.endx = handles.classified_width;
0120
0121 handles.mode = 'browse';
0122
0123
0124 handles.submode = 'select';
0125
0126
0127
0128 handles.quickmode = logical(0);
0129
0130
0131
0132 handles.lastsegment = 1;
0133
0134
0135 handles.sortclass = 'length';
0136
0137
0138
0139
0140
0141 set(handles.SortPopupMenu,'Value',3);
0142
0143 handles.lastclass = 0;
0144
0145 handles.lowerfreq = 0;
0146 handles.upperfreq = 7500;
0147 handles.rezoom = logical(1);
0148
0149 handles.IconListf = {};
0150
0151 handles.baseclassname = 'mockingbird';
0152
0153 handles.nclasses = 0;
0154 handles.classes = [];
0155 handles.current_class = 0;
0156
0157 handles.configschanged = logical(0);
0158
0159 handles.precomputed = logical(0);
0160
0161 handles.configfile = 'class_spec.conf';
0162
0163 handles.originalsize = [0 0 170 44];
0164 handles.originalaxessize = [80.5 6.375 86.167 34.438];
0165 handles.blank = logical(1);
0166 handles.prevsize = handles.originalsize;
0167
0168 handles.fixed = logical(1);
0169
0170
0171 handles.nfeatures = 10;
0172 handles.ncepestral = 10;
0173
0174 set(gcf, 'ResizeFcn', {@ResizeFcn});
0175
0176
0177 guidata(hObject, handles);
0178
0179
0180
0181
0182
0183 function varargout = classify_spectra_OutputFcn(hObject, eventdata, handles)
0184
0185
0186
0187
0188
0189
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
0206
0207
0208 function segments=LoadSegmentsFromDirectory(directory)
0209 segfilelist = dir( [directory '\*' '.seg.txt'] );
0210
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
0218 scanned=fscanf( fid, '%g %g',[2 inf] );
0219 fclose(fid);
0220
0221 wavfile = segfilename(1:(length(segfilename)-8));
0222 i = 1;
0223 while i <= size(scanned, 2)
0224 segment.wavfile = wavfile;
0225 segment.class = '';
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
0239 handles.segments = LoadSegmentsFromDirectory(handles.directory);
0240 handles.nsegments = length(handles.segments);
0241 guidata(hObject, handles);
0242
0243
0244
0245
0246
0247 function handles = cindex2imagelist(handles)
0248
0249 handles.image_list = {};
0250
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
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
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
0277
0278
0279 nbaseclass = length(handles.baseclassname);
0280 classnum = 0;
0281 for i = 1:handles.nclasses
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
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
0303 handles.nclasses = length(handles.classes);
0304 class.name = newclassname(handles);
0305 class.nmembers = 1;
0306 class.specfilename = segment.specfilename;
0307 class.index = handles.NextIndex;
0308
0309 class.iconS = handles.IconList{handles.NextIndex};
0310 class.length = segment.end - segment.start;
0311
0312 handles.classes = [handles.classes class];
0313 handles.nclasses = handles.nclasses + 1;
0314
0315 ;
0316
0317 function handles=ConfigureClassSegment(handles)
0318
0319 segment = handles.segments(handles.NextIndex);
0320 if strcmp(segment.class,'')
0321 set(handles.ClassifyButton,'String','Classify');
0322 set(handles.ClassifyButton,'Enable','on');
0323 else
0324 set(handles.ClassifyButton,'String','Declassify');
0325 set(handles.ClassifyButton,'Enable','on');
0326 end
0327
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
0339 function ClassifyButton_Callback(hObject, eventdata, handles)
0340
0341
0342
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
0349 set(handles.RenameClassButton,'Visible','off');
0350 handles.startx = 1;
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
0365 if strcmp(handles.mode,'comparison')
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
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
0387 handles = blankaxes(handles);
0388 handles.mode = 'class-view';
0389 handles.submode = 'select-class';
0390 set(handles.hiclass,'ButtonDownFcn',{@DummyClassifyAxesClickCallBack,handles});
0391 end
0392
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
0397 if length(handles.classes) == 1
0398 axes(handles.ClassifiedAxes);
0399 handles.classes = [];
0400 handles.nclasses = 0;
0401 handles = blankaxes(handles);
0402 else
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;
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 = '';
0420 if handles.nclasses >= 1
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 ;
0429 end
0430 end
0431 set(handles.ClassifyButton,'String','Classify');
0432
0433 setnavigationbuttons(handles);
0434 end
0435 guidata(gcbo,handles);
0436
0437
0438
0439 function NewClassButton_Callback(hObject, eventdata, handles)
0440
0441
0442
0443
0444 handles.startx = 1;
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
0470 function RemoveClassButton_Callback(hObject, eventdata, handles)
0471
0472
0473
0474
0475
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
0484 function TypifyClassButton_Callback(hObject, eventdata, handles)
0485
0486
0487
0488
0489 set(handles.TypifyClassButton,'Enable','off');
0490
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
0498
0499
0500 function segment=precompute_spectra(handles, segment)
0501
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
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
0513 [data] = wavread(segment.wavfile, [1 spec_iend + spec_ipad]);
0514 else
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);
0522
0523 wavlength = length(data);
0524 Ssize = size(Sfull);
0525
0526 Slength = Ssize(2);
0527 RatioWS = Slength / (wavlength / handles.Fs);
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
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);
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
0565
0566
0567 function handles=get_and_plot(handles, segment)
0568 load('-mat',segment.specfilename);
0569 axes(handles.ToClassifyAxes);
0570
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
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
0588 [data] = wavread(segment.wavfile, [1 wav_iend + wav_ipad]);
0589 else
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
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
0661
0662
0663
0664
0665
0666 ih = image(tsmall,f,flipud(ispecFull));
0667 axis xy;
0668 ;
0669
0670 function PlotModeCallBack(src,eventdata)
0671
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
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
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
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
0740
0741 handles.directory = get(handles.DirectoryEditBox,'String');
0742
0743
0744
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
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);
0787
0788 if not(strcmp(handles.segments(handles.NextIndex).class,''))
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
0799
0800 function PlaySegmentButton_Callback(hObject, eventdata, handles)
0801
0802
0803
0804
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
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
0832
0833 Ssize = size(S);
0834 iconS = zeros(height,Ssize(2));
0835
0836
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)
0846 iconS(height,j) = mean(S(rf*(height-1) : Ssize(1),j));
0847 end
0848 iconS = flipud(iconS);
0849
0850
0851 maxintense = max(max(iconS));
0852 minintense = min(min(iconS));
0853
0854 iconS=uint8(1 + round(255 * (iconS-minintense)/(maxintense-minintense)));
0855
0856
0857
0858
0859
0860 function destination = copy_into(destination,source,r,c)
0861
0862
0863
0864 sized = size(destination);
0865 sizes = size(source);
0866
0867 destination(r:r+sizes(1)-1,c:c+sizes(2)-1) = source(:,:);
0868
0869
0870
0871
0872
0873
0874
0875
0876 function positions = position_images(height,width,images_dim,xspacer,yspacer)
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
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
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
0908 end
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920 function image_dim = get_image_sizes(images)
0921
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
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
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');
0951
0952
0953 function handles = plot_classified_axes(handles, image_list, position_list)
0954
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);
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
0984
0985
0986
0987
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
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
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
1019 cpositions = handles.positions(handles.startpage:handles.endpage,:);
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
1026
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
1033 cposition = i;
1034 end
1035 ;
1036
1037 function cposition = next_row_end(positions,cposition)
1038
1039
1040 npos = length(positions(:,1));
1041 if cposition < npos
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;
1048 else
1049 cposition = i - 1;
1050 end
1051 else
1052 cposition = npos;
1053 end
1054 ;
1055
1056
1057 function handles = row_forward(handles)
1058
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)
1063 handles.startpage = startpage;
1064 handles.endpage = endpage;
1065 end
1066
1067 ;
1068
1069 function cposition = previous_row_start(positions,cposition)
1070
1071
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;
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
1108 nrows = length(unique(handles.positions(handles.startpage:handles.endpage,1)));
1109
1110 function handles = row_backward(handles)
1111
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
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
1126 ;
1127
1128 function handles = BrowseDirectory(handles)
1129
1130
1131
1132
1133
1134
1135
1136
1137
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
1147
1148
1149
1150 function NextRowButton_Callback(hObject, eventdata, handles)
1151
1152
1153
1154
1155 if handles.cnrows > 1
1156 handles.startx = 1;
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
1166 function PreviousRowButton_Callback(hObject, eventdata, handles)
1167
1168
1169
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
1182 function LoadDirectoryButton_Callback(hObject, eventdata, handles)
1183
1184
1185
1186
1187
1188
1189 directoryname = uigetdir;
1190
1191 if not(directoryname == 0)
1192 handles.directory = directoryname;
1193 set(handles.DirectoryEditBox, 'String',directoryname);
1194 cd(handles.directory);
1195 end
1196 guidata(gcbo,handles);
1197 ;
1198
1199 function im_index = coordinate2index(handles,xpos,ypos)
1200
1201
1202
1203
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
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)
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
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
1276 handles = guidata(gcbo);
1277
1278
1279
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
1286 set_status(handles,'');
1287 else
1288 handles.startx = 1;
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
1297 handles = quick_mode_exit(handles);
1298 set(handles.QuickModeButton,'Value',0);
1299 handles.quickmode = not(handles.quickmode);
1300 end
1301 end
1302 else
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
1311
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
1322 if strcmp('class-view',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
1323 handles.startx = 1;
1324 handles.endx = handles.classified_width;
1325 set(handles.SliderClassified,'Value',0);
1326
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
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
1348 handles.startx = 1;
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;
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
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
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;
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
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;
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
1483
1484 guidata(gcf,handles);
1485
1486
1487
1488
1489
1490 function handles = configureclassview(handles,submode)
1491
1492 handles.mode = 'class-view';
1493 handles.submode = submode;
1494
1495
1496
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
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);
1516
1517 if cnrow > handles.number_rows
1518 for i = 1:(cnrow - handles.number_rows)
1519 handles = row_forward(handles);
1520 end
1521
1522 if not(handles.endpage == length(handles.positions))
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
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)
1548 set(handles.ModePopupMenu,'Value',[i]);
1549 end
1550
1551
1552 function ModePopupMenu_Callback(hObject, eventdata, handles)
1553
1554
1555
1556
1557
1558
1559
1560
1561 handles.startx = 1;
1562 handles.endx = handles.classified_width;
1563 set(handles.SliderClassified,'Value',0);
1564
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
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
1620 function ModePopupMenu_CreateFcn(hObject, eventdata, handles)
1621
1622
1623
1624
1625
1626
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
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
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
1657 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1658
1659 else
1660 handles = blankaxes(handles);
1661
1662
1663 set_status(handles,'');
1664 end
1665 ;
1666
1667 function indexfilter = select_class(handles,segments,classname)
1668
1669
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
1689 value = handles.mapindex(index);
1690
1691
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)
1712 classes = [classes(1:j-1) classes(j+1:nclasses)];
1713 typify = '*';
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)];
1726 fclose(fid);
1727 ;
1728
1729 function handles = merge_syllable_database(handles,data)
1730
1731
1732
1733 specfilenames = data{1};
1734 classnames = data{2};
1735 typifies = data{3};
1736 ndata = length(specfilenames);
1737
1738 handles.classes = [];
1739 handles.nclasses = 0;
1740 for i = 1:ndata
1741 j=1;
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),'*')
1748
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;
1755 handles.nclasses = handles.nclasses + 1;
1756 handles.classes = [handles.classes class];
1757 end
1758 end
1759 end
1760
1761
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
1772 function SaveButton_Callback(hObject, eventdata, handles)
1773
1774
1775
1776
1777 write_syllable_database(handles);
1778 save_configuration(handles,handles.configfile);
1779
1780
1781
1782 function SliderClassified_Callback(hObject, eventdata, handles)
1783
1784
1785
1786
1787
1788
1789
1790 xposition = round(get(hObject,'Value'));
1791
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);
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
1806 function SliderClassified_CreateFcn(hObject, eventdata, handles)
1807
1808
1809
1810
1811
1812
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
1821 function SortPopupMenu_Callback(hObject, eventdata, handles)
1822
1823
1824
1825
1826
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
1845 function SortPopupMenu_CreateFcn(hObject, eventdata, handles)
1846
1847
1848
1849
1850
1851
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
1870
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
1886 function RenameClassButton_Callback(hObject, eventdata, handles)
1887
1888
1889
1890
1891 class = handles.classes(handles.lastclass);
1892 answer = inputdlg({'Class name'},'Edit class name',1,{class.name});
1893
1894
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')
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;
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
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
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
1982 handles.classes(j).iconS = handles.IconList{handles.classes(j).index};
1983 end
1984
1985 nimages = length(handles.mapindex);
1986
1987
1988 if not(strcmp(handles.mode,'class-view')) && not(strcmp(handles.mode,'comparison'))
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
2007 function ZoomButton_Callback(hObject, eventdata, handles)
2008
2009
2010
2011
2012 status = get(handles.ZoomButton,'String');
2013
2014 handles = ZoomSpectra(handles,status);
2015
2016 guidata(gcbo,handles);
2017
2018
2019
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
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
2060 function QuickModeButton_Callback(hObject, eventdata, handles)
2061
2062
2063
2064
2065 if not(handles.quickmode)
2066
2067 handles.quickmode = 1;
2068
2069
2070 set(handles.ViewText,'Visible','off');
2071 set(handles.ModePopupMenu,'Visible','off');
2072 set(handles.SegInfoText,'Visible','off');
2073
2074
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
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
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
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
2117 end
2118
2119 guidata(gcbo,handles);
2120
2121 function handles=jump_to_unclassified(handles)
2122
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)
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
2136 handles.lastsegment = currindex;
2137
2138
2139 function SkipButton_Callback(hObject, eventdata, handles)
2140
2141
2142
2143 handles = jump_to_unclassified(handles);
2144
2145 if handles.lastsegment == handles.NextIndex
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
2155 function UndoButton_Callback(hObject, eventdata, handles)
2156
2157
2158
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
2172 function NewQuickButton_Callback(hObject, eventdata, handles)
2173
2174
2175
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
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
2196 function CompareToggleButton_Callback(hObject, eventdata, handles)
2197
2198
2199
2200
2201
2202
2203 state = get(hObject,'Value');
2204
2205 if handles.nclasses > 0
2206
2207 if state
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')
2224 set(hObject,'Value',1);
2225 handles.startx = 1;
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')
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
2253
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);
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)
2305 newsize(3) = originalsize(3);
2306 classaxpos(3) = handles.originalaxessize(3);
2307
2308 sliderpos = get(handles.SliderClassified,'Position');
2309 sliderpos(3) = classaxpos(3);
2310 set(handles.SliderClassified,'Position',sliderpos);
2311
2312 else
2313 deltax = newsize(3) - handles.prevsize(3);
2314 classaxpos(3) = classaxpos(3) + deltax;
2315
2316 sliderpos = get(handles.SliderClassified,'Position');
2317 sliderpos(3) = sliderpos(3) + deltax;
2318 set(handles.SliderClassified,'Position',sliderpos);
2319
2320 end
2321
2322 if originalsize(4) > newsize(4)
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
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
2340
2341 handles.classified_width_density = handles.classified_width / classaxpos(3);
2342 handles.classified_height_density = handles.classified_height / classaxpos(4);
2343 else
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
2355 function ConfigureButton_Callback(hObject, eventdata, handles)
2356
2357
2358
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)
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;
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
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);
2424
2425 handles=ConfigureSpecPlot(handles);
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
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');
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);
2454 end
2455 end
2456
2457 if not(handles.configschanged)
2458 if not(recompute)
2459 handles.configschanged = logical(1);
2460 end
2461 end
2462
2463 if redraw
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
2505 function NextClassButton_Callback(hObject, eventdata, handles)
2506
2507
2508
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
2533
2534
2535
2536
2537
2538
2539
2540
2541 waitbar(i/handles.nsegments);
2542
2543 handles.segments(i).features = cepestral';
2544
2545
2546
2547
2548
2549
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;
2556
2557
2558
2559
2560
2561
2562
2563
2564 Sdiff = exp(S) - sbase;
2565 spectra = log(mean(Sdiff'));
2566
2567
2568
2569 cepstrum = real(ifft(spectra));
2570
2571
2572
2573
2574
2575 coefs = cepstrum(1:ncepestral);
2576
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);
2589 handles.classes = [];
2590 handles.nclasses = 0;
2591 j = 1;
2592 for i = 1:handles.nsegments
2593 if classification(i) == 0
2594 handles.segments(i).class = '';
2595 else
2596 if isempty(classesfound(find(classesfound == classification(i))))
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
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
2618 function AutoClassifyButton_Callback(hObject, eventdata, handles)
2619
2620
2621
2622
2623 if length(handles.segments(1).features) == 0;
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
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');
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
2652
2653
2654
2655
2656
2657 end
2658 guidata(gcbo,handles);
2659
2660
2661
2662 function FileMenu_Callback(hObject, eventdata, handles)
2663
2664
2665
2666
2667
2668
2669 function SaveItem_Callback(hObject, eventdata, handles)
2670
2671
2672
2673
2674 SaveButton_Callback(hObject, eventdata, handles)
2675
2676
2677 function LoadItem_Callback(hObject, eventdata, handles)
2678
2679
2680
2681
2682 PrecomputeButton_Callback(hObject, eventdata, handles)
2683
2684
2685
2686
2687 function HelpMenu_Callback(hObject, eventdata, handles)
2688
2689
2690
2691
2692
2693
2694 function HelpItem_Callback(hObject, eventdata, handles)
2695
2696
2697
2698
2699 web('classify_spectra_help.html');
2700
2701
2702 function AboutItem_Callback(hObject, eventdata, handles)
2703
2704
2705
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
2713
2714
2715
2716 ConfigureButton_Callback(hObject, eventdata, handles)
2717
2718 function coefs = cepcoefs(data,p)
2719
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};
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
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
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
2809 fprintf(fp,delimiter);
2810 else
2811 if i < handles.nsegments
2812 fprintf(fp,'\n');
2813 end
2814 end
2815 end
2816 end
2817 fclose(fp);
2818
2819 function ExportDataItem_Callback(hObject, eventdata, handles)
2820
2821
2822
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
2837
2838
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