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 directoryname = uigetdir('','Change directory');
1188
1189 if not(directoryname == 0)
1190 handles.directory = directoryname;
1191 set(handles.DirectoryEditBox, 'String',directoryname);
1192 cd(handles.directory);
1193 end
1194 guidata(gcbo,handles);
1195 ;
1196
1197 function im_index = coordinate2index(handles,xpos,ypos)
1198
1199
1200
1201
1202 if (xpos < 0) || (ypos < 0) || (ypos > handles.classified_height) || (xpos > handles.classified_width)
1203 im_index = 0;
1204 else
1205 im_index = 0;
1206 npos = length(handles.cpositions(:,1));
1207 i = 1;
1208 while (i <= npos) && (im_index < 1)
1209 if (xpos >= handles.cpositions(i,2)) && (xpos <= (handles.cpositions(i,2) + handles.images_dim(handles.startpage + (i-1), 2)))
1210 if (ypos >= handles.cpositions(i,1)) && (ypos <= (handles.cpositions(i,1) + handles.images_dim(handles.startpage + (i-1),1)))
1211 im_index = i;
1212 end
1213 end
1214 i = i+1;
1215 end
1216 end
1217 ;
1218
1219 function setnavigationbuttons(handles)
1220
1221
1222 if not(handles.quickmode)
1223
1224 if handles.NextIndex == handles.nsegments
1225 set(handles.PreviousSpectraButton,'Enable','off');
1226 set(handles.NextSpectraButton,'Enable','off');
1227 elseif handles.NextIndex == handles.nsegments
1228 set(handles.NextSpectraButton,'Enable','off');
1229 set(handles.PreviousSpectraButton,'Enable','on');
1230 elseif handles.NextIndex == 1
1231 set(handles.PreviousSpectraButton,'Enable','off');
1232 set(handles.NextSpectraButton,'Enable','on');
1233 elseif (handles.NextIndex > 1) && (handles.NextIndex < handles.nsegments)
1234 set(handles.PreviousSpectraButton,'Enable','on');
1235 set(handles.NextSpectraButton,'Enable','on');
1236
1237 end
1238
1239 end
1240
1241 function setrowbuttons(handles)
1242
1243 if handles.startpage == 1
1244 set(handles.PreviousRowButton,'Enable','off');
1245 elseif handles.startpage > 1
1246 set(handles.PreviousRowButton,'Enable','on');
1247 end
1248
1249 if handles.endpage == length(handles.positions)
1250 set(handles.NextRowButton,'Enable','off');
1251 elseif handles.cnrows <= handles.number_rows
1252 set(handles.NextRowButton,'Enable','off');
1253 elseif handles.endpage < length(handles.positions)
1254 set(handles.NextRowButton,'Enable','on');
1255 end
1256
1257 function DummyClassifyAxesClickCallBack(src,eventdata,handles)
1258
1259 set(handles.ClassifyButton,'Enable','on');
1260 set(handles.NewClassButton,'Visible','off');
1261 set(handles.NextSpectraButton,'Enable','on');
1262 set(handles.PreviousSpectraButton,'Enable','on');
1263 set(handles.ModePopupMenu,'Enable','on');
1264 set(handles.AutoClassifyButton,'Enable','on');
1265 set(handles.QuickModeButton,'Enable','on');
1266 set(handles.CompareToggleButton,'Enable','on');
1267 handles.submode = 'select';
1268 setnavigationbuttons(handles);
1269 guidata(gcbo,handles);
1270
1271
1272 function ClassifyAxesClickCallBack(src,eventdata)
1273
1274 handles = guidata(gcbo);
1275
1276
1277
1278
1279 pos = get(handles.ClassifiedAxes,'CurrentPoint');
1280 cposition = coordinate2index(handles,pos(1,1),pos(1,2));
1281
1282 if handles.quickmode
1283 if cposition == 0
1284 set_status(handles,'');
1285 else
1286 handles.startx = 1;
1287 handles.endx = handles.classified_width;
1288 set(handles.SliderClassified,'Value',0);
1289 class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
1290 handles.segments(handles.NextIndex).class = class.name;
1291 handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers = handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers + 1;
1292 handles = jump_to_unclassified(handles);
1293 handles = configureclassview(handles,'select-class');
1294 if handles.lastsegment == handles.NextIndex
1295 handles = quick_mode_exit(handles);
1296 set(handles.QuickModeButton,'Value',0);
1297 handles.quickmode = not(handles.quickmode);
1298 end
1299 end
1300 else
1301
1302
1303 if strcmp(handles.mode,'browse') && (cposition > 0)
1304 handles.NextIndex = handles.mapindex((cposition - 1) + handles.startpage);
1305 handles=ConfigureClassSegment(handles);
1306 handles=ConfigureSpecPlot(handles);
1307 else
1308
1309
1310 ;
1311 end
1312
1313 if strcmp('class-members',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
1314 handles.NextIndex = handles.mapindex((cposition - 1) + handles.startpage);
1315 handles=ConfigureClassSegment(handles);
1316 handles=ConfigureSpecPlot(handles);
1317 end
1318
1319
1320 if strcmp('class-view',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
1321 handles.startx = 1;
1322 handles.endx = handles.classified_width;
1323 set(handles.SliderClassified,'Value',0);
1324
1325 cindex = handles.mapindex(cposition + (handles.startpage - 1));
1326 class = handles.classes(cindex);
1327 handles.lastclass = cindex;
1328 handles = configureclassmembers(handles,class.name);
1329 handles.mode = 'class-members';
1330 handles.submode = 'select';
1331 handles = SetModePopupMenu(handles,'class members');
1332 set(handles.TypifyClassButton,'Visible','on');
1333 set(handles.RemoveClassButton,'Visible','off');
1334 set(handles.NextClassButton,'Visible','on');
1335 set(handles.RenameClassButton,'Visible','on');
1336 set_status(handles, ['Viewing ' num2str(length(handles.mapindex)),' members of ' class.name]);
1337 end
1338
1339 if strcmp('class-view',handles.mode) && strcmp('select-class',handles.submode)
1340 if cposition == 0
1341 set(handles.ClassifyButton,'Enable','on');
1342 set(handles.NewClassButton,'Visible','off');
1343 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
1344
1345 else
1346 handles.startx = 1;
1347 handles.endx = handles.classified_width;
1348 set(handles.SliderClassified,'Value',0);
1349 class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
1350 handles.segments(handles.NextIndex).class = class.name;
1351 handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers = handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers + 1;
1352 set(handles.ClassifyButton,'String','Declassify');
1353 handles = SetModePopupMenu(handles,'class members');
1354 handles = configureclassmembers(handles,class.name);
1355 handles.mode = 'class-members';
1356 handles.submode = 'select';
1357 set_status(handles,['Classified segment as ' class.name]);
1358 end
1359 set(handles.CompareToggleButton,'Enable','on');
1360 set(handles.QuickModeButton,'Enable','on');
1361 set(handles.AutoClassifyButton,'Enable','on');
1362 set(handles.ClassifyButton,'Enable','on');
1363 set(handles.NewClassButton,'Visible','off');
1364 set(handles.NextSpectraButton,'Enable','on');
1365 set(handles.PreviousSpectraButton,'Enable','on');
1366 set(handles.ModePopupMenu,'Enable','on');
1367 set(handles.SortText,'Visible','off');
1368 set(handles.SortPopupMenu,'Visible','off');
1369 handles.submode = 'select';
1370 end
1371
1372 if strcmp(handles.mode,'class-members') && strcmp(handles.submode,'typify')
1373 if cposition == 0
1374 set(handles.TypifyClassButton, 'Enable','on');
1375 else
1376 handles.startx = 1;
1377 handles.endx = handles.classified_width;
1378 set(handles.SliderClassified,'Value',0);
1379 sindex = handles.mapindex(cposition + (handles.startpage - 1));
1380 cindex = returnclassindex(handles,handles.segments(sindex).class);
1381 handles.classes(cindex).specfilename = handles.segments(sindex).specfilename;
1382 handles.classes(cindex).length = handles.segments(sindex).end - handles.segments(sindex).start;
1383 handles.classes(cindex).index = sindex;
1384
1385 handles.classes(cindex).iconS = handles.IconList{sindex};
1386 handles.subclass = 'xxx';
1387 set(handles.TypifyClassButton, 'Enable','on');
1388 set_status(handles,'');
1389 end
1390 end
1391
1392 if strcmp('class-view', handles.mode) && strcmp('compare',handles.submode)
1393 if cposition == 0
1394 handles.mode = 'class-view';
1395 handles.submode = 'select';
1396 set(handles.CompareToggleButton,'Enable','on');
1397 set(handles.RemoveClassButton,'Enable','on');
1398 set(handles.NextSpectraButton,'Enable','on');
1399 set(handles.PreviousSpectraButton,'Enable','on');
1400
1401 else
1402 handles.mode = 'comparison';
1403 if strcmp(handles.segments(handles.NextIndex).class,'')
1404 set(handles.ClassifyButton,'Enable','on');
1405 end
1406 handles.startx = 1;
1407 handles.endx = handles.classified_width;
1408 set(handles.SliderClassified,'Value',0);
1409 cindex = handles.mapindex(cposition + (handles.startpage - 1));
1410 handles.image_list = {};
1411 handles.lastclass = cindex;
1412 handles.image_list{2} = handles.classes(cindex).iconS;
1413
1414 handles.image_list{1} = handles.IconList{handles.NextIndex};
1415
1416 set_status(handles,['Comparing to ' handles.classes(cindex).name]);
1417
1418 handles = reposition_images(handles, handles.image_list);
1419 handles.cpositions = get_curr_position(handles);
1420 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1421 handles.submode = 'xxx';
1422 end
1423 end
1424
1425
1426 if strcmp(handles.mode,'class-view') && strcmp(handles.submode,'remove-class')
1427 if cposition == 0
1428 handles.submode = 'select';
1429 set(handles.RemoveClassButton, 'Enable','on');
1430 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
1431 else
1432 cindex = handles.mapindex(cposition + (handles.startpage - 1));
1433 classname = handles.classes(cindex).name;
1434
1435 answer = questdlg(['Remove class ' classname]);
1436
1437 if strcmp(answer,'Yes')
1438 handles.startx = 1;
1439 handles.endx = handles.classified_width;
1440 set(handles.SliderClassified,'Value',0);
1441 for i = 1:handles.nsegments
1442 if strcmp(classname,handles.segments(i).class)
1443 handles.segments(i).class = '';
1444 end
1445 end
1446
1447 if handles.nclasses > 1
1448 handles.classes = [handles.classes(1:(cindex-1)) handles.classes((cindex+1):handles.nclasses)];
1449 handles.nclasses = handles.nclasses - 1;
1450 handles = configureclassview(handles,'select');
1451
1452 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
1453 else
1454 handles.classes = [];
1455 handles.nclasses = 0;
1456 handles.image_list = {};
1457 set_status(handles,'');
1458 set(handles.RemoveClassButton,'Visible','off');
1459 handles.submode = 'xxx';
1460 handles = blankaxes(handles);
1461 end
1462
1463 if strcmp(handles.segments(handles.NextIndex).class,'')
1464 set(handles.ClassifyButton,'String','Classify');
1465 end
1466 set(handles.RemoveClassButton, 'Enable','on');
1467 else
1468 handles.submode = 'select';
1469 set(handles.RemoveClassButton, 'Enable','on');
1470 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
1471 end
1472 end
1473 end
1474
1475 end
1476
1477 if not(strcmp(handles.mode,'comparison'))
1478 setnavigationbuttons(handles);
1479 end
1480
1481
1482 guidata(gcf,handles);
1483
1484
1485
1486
1487
1488 function handles = configureclassview(handles,submode)
1489
1490 handles.mode = 'class-view';
1491 handles.submode = submode;
1492
1493
1494
1495 handles.mapindex = [1 : handles.nclasses];
1496
1497 if strcmp(handles.sortclass, 'popularity')
1498 handles.mapindex = sortindexbypop(handles);
1499 elseif strcmp(handles.sortclass,'length');
1500 handles.mapindex = sortindexbylength(handles);
1501 else
1502 handles.mapindex = [1 : handles.nclasses];
1503 end
1504 handles = cindex2imagelist(handles);
1505 handles = reposition_images(handles, handles.image_list);
1506
1507 if (strcmp(handles.sortclass,'length') && strcmp(handles.submode,'select-class')) || (strcmp(handles.sortclass,'length') && strcmp(handles.submode,'compare'))
1508
1509 i = 1;
1510 while (i <= handles.nclasses) && (handles.classes(handles.mapindex(i)).length >= (handles.segments(handles.NextIndex).end - handles.segments(handles.NextIndex).start))
1511 i = i + 1;
1512 end
1513 cnrow = which_row(handles.positions,i-1);
1514
1515 if cnrow > handles.number_rows
1516 for i = 1:(cnrow - handles.number_rows)
1517 handles = row_forward(handles);
1518 end
1519
1520 if not(handles.endpage == length(handles.positions))
1521 nrows = floor(handles.number_rows / 2);
1522 for i = 1:nrows
1523 handles = row_forward(handles);
1524 end
1525 end
1526
1527
1528 end
1529 end
1530
1531 handles.cpositions = get_curr_position(handles);
1532 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1533
1534 ;
1535
1536 function handles = SetModePopupMenu(handles,viewstring)
1537 popmodes = get(handles.ModePopupMenu,'String');
1538
1539 find_index = 0;
1540 i = 1;
1541 while (i <= length(popmodes)) && not(strcmp(popmodes(i),viewstring))
1542 i = i + 1;
1543 end
1544
1545 if i <= length(popmodes)
1546 set(handles.ModePopupMenu,'Value',[i]);
1547 end
1548
1549
1550 function ModePopupMenu_Callback(hObject, eventdata, handles)
1551
1552
1553
1554
1555
1556
1557
1558
1559 handles.startx = 1;
1560 handles.endx = handles.classified_width;
1561 set(handles.SliderClassified,'Value',0);
1562
1563 set(handles.RenameClassButton, 'Visible', 'off');
1564
1565 nmode = get(hObject,'Value');
1566 modeview = get(hObject,'String');
1567
1568
1569 if strcmp(modeview(nmode),'all')
1570 handles.mode = 'browse';
1571 handles.submode = 'select';
1572 handles=BrowseDirectory(handles);
1573 set(handles.RemoveClassButton,'Visible','off');
1574 set(handles.TypifyClassButton, 'Visible', 'off');
1575 set(handles.NextClassButton,'Visible','off');
1576
1577 elseif strcmp(modeview(nmode),'class view')
1578 set(handles.NextClassButton,'Visible','off');
1579 if handles.nclasses >= 1
1580 handles = configureclassview(handles,'select');
1581 handles.mode = 'class-view';
1582 handles.submode = 'select';
1583 set(handles.RemoveClassButton,'Visible','on');
1584 set(handles.RemoveClassButton,'Enable','on');
1585 set(handles.CompareToggleButton,'Visible','on');
1586 set(handles.CompareToggleButton,'Enable','on');
1587 set(handles.TypifyClassButton, 'Visible', 'off');
1588 set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes'])
1589 else
1590 handles = blankaxes(handles);
1591 handles.mode = 'class-view';
1592 handles.submode = 'xxx';
1593 set_status(handles,'');
1594 end
1595 elseif strcmp(modeview(nmode),'unclassified') || (strcmp(handles.segments(handles.NextIndex).class,'') && strcmp(modeview(nmode),'class members'))
1596 handles = configureclassmembers(handles,'');
1597 set_status(handles,['A total of ' num2str(length(handles.mapindex)) ' unclassified segments ']);
1598 handles = SetModePopupMenu(handles,'unclassified');
1599 handles.mode = 'browse';
1600 handles.submode = 'select';
1601 set(handles.RemoveClassButton, 'Visible', 'off');
1602 set(handles.TypifyClassButton,'Visible','off');
1603 set(handles.NextClassButton,'Visible','off');
1604 elseif strcmp(modeview(nmode),'class members')
1605 handles = configureclassmembers(handles,handles.segments(handles.NextIndex).class);
1606 set_status(handles,['Viewing ' num2str(length(handles.mapindex)) ' members of ' handles.segments(handles.NextIndex).class]);
1607 handles.mode = 'class-members';
1608 handles.submode = 'select';
1609 handles.lastclass = get_class_index(handles,handles.segments(handles.NextIndex).class);
1610 set(handles.TypifyClassButton,'Visible', 'on');
1611 set(handles.RemoveClassButton, 'Visible', 'off');
1612 set(handles.RenameClassButton,'Visible','on');
1613 set(handles.NextClassButton,'Visible','on');
1614 end
1615 guidata(gcbo,handles);
1616
1617
1618 function ModePopupMenu_CreateFcn(hObject, eventdata, handles)
1619
1620
1621
1622
1623
1624
1625 if ispc
1626 set(hObject,'BackgroundColor','white');
1627 else
1628 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
1629 end
1630
1631 function set_status(handles, statusstring)
1632 set(handles.SegInfoText,'String',statusstring);
1633 set(handles.SegInfoText,'Visible','on');
1634 ;
1635
1636
1637
1638
1639
1640 function handles = configureclassmembers(handles,classname)
1641
1642 handles.mapindex = select_class(handles,handles.segments,classname);
1643
1644 if length(handles.mapindex) > 0
1645 handles.image_list = {};
1646
1647
1648 for i = 1:length(handles.mapindex)
1649 handles.image_list(i) = handles.IconList(handles.mapindex(i));
1650 end
1651 handles = reposition_images(handles, handles.image_list);
1652 handles.cpositions = get_curr_position(handles);
1653
1654
1655 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1656
1657 else
1658 handles = blankaxes(handles);
1659
1660
1661 set_status(handles,'');
1662 end
1663 ;
1664
1665 function indexfilter = select_class(handles,segments,classname)
1666
1667
1668 indexfilter = [];
1669 nclassmembers = 0;
1670 for i = 1:handles.nsegments
1671 if strcmp(segments(i).class,classname)
1672 nclassmembers = nclassmembers + 1;
1673 indexfilter(nclassmembers) = i;
1674 end
1675 end
1676
1677 function cindex = get_class_index(handles,classname);
1678 cindex = 0;
1679 i = 1;
1680 while (i <= handles.nclasses) && not(strcmp(handles.classes(i).name,classname))
1681 i = i + 1;
1682 end
1683 cindex = i;
1684
1685 function value = mapind(index)
1686
1687 value = handles.mapindex(index);
1688
1689
1690 function write_syllable_database(handles)
1691 filename = [handles.baseclassname '.dat'];
1692 fid = fopen(filename,'wt');
1693
1694 classes = handles.classes;
1695
1696 if fid > -1
1697 for i = 1:handles.nsegments
1698 segment = handles.segments(i);
1699 wavfile = segment.wavfile;
1700 specfilename = segment.specfilename;
1701 seg = [ num2str(segment.start) '\t' num2str(segment.end)];
1702 classname = [ segment.class ];
1703 typify = '';
1704 nclasses = length(classes);
1705 j = 1;
1706 while (nclasses > 0) && (j <= nclasses) && not(strcmp(segment.specfilename,classes(j).specfilename))
1707 j = j + 1;
1708 end
1709 if j <= length(classes)
1710 classes = [classes(1:j-1) classes(j+1:nclasses)];
1711 typify = '*';
1712 end
1713 fprintf(fid,[specfilename '\t' wavfile '\t' seg '\t' classname '\t' typify '\n']);
1714 end
1715 fclose(fid);
1716 end
1717 ;
1718
1719 function data = read_syllable_database(handles)
1720 filename = [handles.baseclassname '.dat'];
1721 fid = fopen(filename,'rt');
1722 data = textscan(fid,'%s %s %n %n %s %s', 'delimiter','\t');
1723 data = [data(1), data(5), data(6)];
1724 fclose(fid);
1725 ;
1726
1727 function handles = merge_syllable_database(handles,data)
1728
1729
1730
1731 specfilenames = data{1};
1732 classnames = data{2};
1733 typifies = data{3};
1734 ndata = length(specfilenames);
1735
1736 handles.classes = [];
1737 handles.nclasses = 0;
1738 for i = 1:ndata
1739 j=1;
1740 while (j < handles.nsegments) && not(strcmp(specfilenames(i),handles.segments(j).specfilename))
1741 j = j + 1;
1742 end
1743 if j <= handles.nsegments
1744 handles.segments(j).class = classnames{i};
1745 if strcmp(typifies(i),'*')
1746
1747 class.specfilename = specfilenames{i};
1748 class.name = classnames{i};
1749 class.index = j;
1750 class.length = handles.segments(j).end - handles.segments(j).start;
1751 class.iconS = handles.IconList{j};
1752 class.nmembers = 0;
1753 handles.nclasses = handles.nclasses + 1;
1754 handles.classes = [handles.classes class];
1755 end
1756 end
1757 end
1758
1759
1760 for i = 1:handles.nclasses
1761 for j = 1 : handles.nsegments
1762 if strcmp(handles.classes(i).name,handles.segments(j).class)
1763 handles.classes(i).nmembers = handles.classes(i).nmembers + 1;
1764 end
1765 end
1766 end
1767
1768
1769
1770 function SaveButton_Callback(hObject, eventdata, handles)
1771
1772
1773
1774
1775 write_syllable_database(handles);
1776 save_configuration(handles,handles.configfile);
1777
1778
1779
1780 function SliderClassified_Callback(hObject, eventdata, handles)
1781
1782
1783
1784
1785
1786
1787
1788 xposition = round(get(hObject,'Value'));
1789
1790 handles.startx = 1 + xposition;
1791 handles.endx = xposition + handles.classified_width;
1792 handles.cpositions = get_curr_position(handles);
1793 classview = handles.classmatrix(:,handles.startx:handles.endx);
1794 axes(handles.ClassifiedAxes);
1795 handles.hiclass = image(classview);
1796
1797 set(handles.hiclass,'ButtonDownFcn',{@ClassifyAxesClickCallBack});
1798 set(handles.ClassifiedAxes,'XTick',[]);
1799 set(handles.ClassifiedAxes,'YTick',[]);
1800
1801 guidata(hObject, handles);
1802
1803
1804 function SliderClassified_CreateFcn(hObject, eventdata, handles)
1805
1806
1807
1808
1809
1810
1811 usewhitebg = 1;
1812 if usewhitebg
1813 set(hObject,'BackgroundColor',[.9 .9 .9]);
1814 else
1815 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
1816 end
1817
1818
1819 function SortPopupMenu_Callback(hObject, eventdata, handles)
1820
1821
1822
1823
1824
1825
1826 sortlist = get(hObject,'String');
1827 sortn = get(hObject,'Value');
1828 sortby = sortlist(sortn);
1829
1830 if strcmp(sortby,'original')
1831 handles.sortclass = 'original';
1832 elseif strcmp(sortby,'by length')
1833 handles.sortclass = 'length';
1834 elseif strcmp(sortby,'by popularity')
1835 handles.sortclass = 'popularity';
1836 end
1837
1838 handles = configureclassview(handles,handles.submode);
1839
1840 guidata(gcbo,handles);
1841
1842
1843 function SortPopupMenu_CreateFcn(hObject, eventdata, handles)
1844
1845
1846
1847
1848
1849
1850 if ispc
1851 set(hObject,'BackgroundColor','white');
1852 else
1853 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
1854 end
1855
1856
1857 function segments = rename_segments(segments,oldname,newname)
1858
1859 nsegments = length(segments);
1860 for i = 1 : nsegments
1861 if strcmp(segments(i).class,oldname)
1862 segments(i).class = newname;
1863 end
1864 end
1865
1866 function cln = doesclassexist(classname,classes)
1867
1868
1869
1870 i = 1;
1871 nclasses = length(classes);
1872
1873 while (i <= nclasses) && (strcmp(classname,classes(i).name))
1874 i = i + 1;
1875 end
1876
1877 if i <= nclasses
1878 cln = i;
1879 else
1880 cln = 0;
1881 end
1882
1883
1884 function RenameClassButton_Callback(hObject, eventdata, handles)
1885
1886
1887
1888
1889 class = handles.classes(handles.lastclass);
1890 answer = inputdlg({'Class name'},'Edit class name',1,{class.name});
1891
1892
1893 sizeanswer = size(answer);
1894
1895 secondanswer = '';
1896
1897 if sizeanswer(1)
1898 if not(strcmp(class.name,answer{1}))
1899 classnexists = doesclassexist(answer{1},handles.classes);
1900 if classnexists
1901 secondanswer = questdlg('Class name already exists. Do you want to merge the two classes.')
1902 end
1903 if strcmp(secondanswer,'Yes') || strcmp(secondanswer,'')
1904 segments = rename_segments(handles.segments,class.name,answer{1});
1905 class.name = answer{1};
1906 cindex = handles.lastclass;
1907 handles.classes(cindex) = class;
1908 handles.segments = segments;
1909
1910 if strcmp(secondanswer,'Yes')
1911 handles.classes(classnexists).nmembers = handles.classes(classnexists).nmembers + handles.classes(cindex).nmembers;
1912 handles.classes = [handles.classes(1:(cindex-1)) handles.classes((cindex+1):handles.nclasses)];
1913 handles.nclasses = handles.nclasses - 1;
1914 class.nmembers = handles.classes(classnexists).nmembers;
1915 end
1916 end
1917 handles = configureclassmembers(handles,class.name);
1918 set_status(handles, ['Viewing ' num2str(class.nmembers),' members of ' class.name]);
1919 end
1920 end
1921 guidata(gcbo,handles);
1922
1923
1924 function spectras = subsamplespectra(spectra,lowerfreq,upperfreq,freqrange)
1925
1926
1927 freqsamples = length(spectra(:,1));
1928 freqratio = freqsamples / (freqrange(2) - freqrange(1));
1929
1930 lowerfreqsamp = round(lowerfreq * freqratio) + 1;
1931 upperfreqsamp = round(upperfreq * freqratio) + 1;
1932
1933 if lowerfreqsamp < 1
1934 lowerfreqsamp = 1;
1935 end
1936
1937 if upperfreq > freqsamples
1938 upperfeqsamp = freqsamples;
1939 end
1940
1941 spectras = spectra(lowerfreqsamp:upperfreqsamp,:);
1942
1943 function handles = generate_subsamples_icons(handles)
1944 segments = handles.segments;
1945 IconListf = {};
1946 hw = waitbar(0,'Zooming spectra. . .');
1947 for i = 1:handles.nsegments
1948 load('-mat',segments(i).specfilename);
1949 Ssub = subsamplespectra(S,handles.lowerfreq,handles.upperfreq,handles.fpass);
1950 IconListf{i} = iconify_spec(Ssub,handles.ispecheight);
1951 waitbar(i/handles.nsegments);
1952 end
1953 close(hw);
1954 handles.IconListf = IconListf;
1955
1956
1957 function handles = ZoomSpectra(handles,status)
1958 if strcmp(status,'Zoom in')
1959 if (length(handles.IconListf) == 0) || (handles.rezoom)
1960 handles = generate_subsamples_icons(handles);
1961 handles.rezoom = logical(0);
1962 end
1963 handles.FullIconList = handles.IconList;
1964 set(handles.ZoomButton,'String','Zoom out');
1965 handles.IconList = handles.IconListf;
1966 elseif strcmp(status,'Zoom out');
1967
1968 if handles.rezoom
1969 handles = generate_subsamples_icons(handles);
1970 handles.rezoom = logical(0);
1971 set(handles.ZoomButton,'String','Zoom out');
1972 handles.IconList = handles.IconListf;
1973 else
1974 handles.IconList = handles.FullIconList;
1975 set(handles.ZoomButton,'String','Zoom in');
1976 end
1977 end
1978
1979 for j = 1:handles.nclasses
1980 handles.classes(j).iconS = handles.IconList{handles.classes(j).index};
1981 end
1982
1983 nimages = length(handles.mapindex);
1984
1985
1986 if not(strcmp(handles.mode,'class-view')) && not(strcmp(handles.mode,'comparison'))
1987 for i = 1:nimages
1988 handles.image_list{i} = handles.IconList{handles.mapindex(i)};
1989 end
1990 elseif strcmp(handles.mode,'comparison')
1991 handles.image_list{1} = handles.IconList{handles.NextIndex};
1992 handles.image_list{2} = handles.IconList{handles.classes(handles.lastclass).index};
1993 else
1994 for i = 1:nimages
1995 handles.image_list{i} = handles.IconList{handles.classes(handles.mapindex(i)).index};
1996 end
1997 end
1998
1999 handles=get_and_plot(handles,handles.segments(handles.NextIndex));
2000 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
2001
2002
2003
2004
2005 function ZoomButton_Callback(hObject, eventdata, handles)
2006
2007
2008
2009
2010 status = get(handles.ZoomButton,'String');
2011
2012 handles = ZoomSpectra(handles,status);
2013
2014 guidata(gcbo,handles);
2015
2016
2017
2018
2019
2020 function [meanl sdl] = stat_lengths(handles)
2021 lengthsarray = [];
2022 for i = 1:length(handles.mapindex)
2023 lengthsarray(i) = handles.segments(i).end - handles.segments(i).start;
2024 end
2025 meanl = mean(lengthsarray);
2026 sdl = sd(lengthsarray);
2027
2028
2029
2030
2031
2032
2033 function handles = quick_mode_exit(handles)
2034 set(handles.SkipButton,'Visible','off');
2035 set(handles.UndoButton,'Visible','off');
2036 set(handles.NewQuickButton,'Visible','off');
2037
2038 set(handles.ViewText,'Visible','on');
2039 set(handles.ModePopupMenu,'Visible','on');
2040 set(handles.SegInfoText,'Visible','on');
2041
2042 set(handles.ClassifyButton,'Enable','on');
2043 set(handles.RemoveClassButton,'Enable','on');
2044 set(handles.RemoveClassButton,'Visible','on');
2045 set(handles.CompareToggleButton,'Enable','on');
2046 set(handles.AutoClassifyButton,'Enable','on');
2047 set(handles.SortPopupMenu,'Visible','off');
2048 set(handles.ModePopupMenu,'Value',3);
2049
2050 handles.submode='select';
2051
2052 set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes']);
2053
2054 setnavigationbuttons(handles);
2055
2056
2057
2058 function QuickModeButton_Callback(hObject, eventdata, handles)
2059
2060
2061
2062
2063 if not(handles.quickmode)
2064
2065 handles.quickmode = 1;
2066
2067
2068 set(handles.ViewText,'Visible','off');
2069 set(handles.ModePopupMenu,'Visible','off');
2070 set(handles.SegInfoText,'Visible','off');
2071
2072
2073 set(handles.SkipButton,'Visible','on');
2074 set(handles.SkipButton,'Enable','on');
2075 set(handles.UndoButton,'Visible','on');
2076 set(handles.UndoButton,'Enable','on');
2077 set(handles.NewQuickButton,'Visible','on');
2078 set(handles.NewQuickButton,'Visible','on');
2079
2080 set(handles.SortPopupMenu,'Visible','on');
2081
2082
2083 set(handles.RemoveClassButton,'Visible','off');
2084 set(handles.NextClassButton,'Visible','off');
2085 set(handles.NextSpectraButton,'Enable','off');
2086 set(handles.PreviousSpectraButton,'Enable','off');
2087 set(handles.ClassifyButton,'Enable','off');
2088 set(handles.TypifyClassButton,'Visible','off');
2089 set(handles.RenameClassButton,'Visible','off');
2090 set(handles.CompareToggleButton,'Enable','off');
2091 set(handles.AutoClassifyButton,'Enable','off');
2092
2093
2094 if not(strcmp(handles.segments(handles.NextIndex).class,''))
2095 handles = jump_to_unclassified(handles);
2096 handles.lastsegment = handles.NextIndex;
2097 end
2098
2099 if handles.nclasses >= 1
2100 handles = configureclassview(handles,'select-class');
2101 handles.mode = 'class-view';
2102 handles.submode = 'select-class';
2103 else
2104 handles = blankaxes(handles);
2105 handles.mode = 'class-view';
2106 handles.submode = 'xxx';
2107 end
2108
2109
2110 else
2111 handles.quickmode = 0;
2112 handles = quick_mode_exit(handles);
2113
2114
2115 end
2116
2117 guidata(gcbo,handles);
2118
2119 function handles=jump_to_unclassified(handles)
2120
2121 currindex = handles.NextIndex;
2122 i = currindex;
2123 while (mod(i,handles.nsegments)+1 ~= currindex) && not(strcmp(handles.segments(mod(i,handles.nsegments) + 1).class,''))
2124 i = i + 1;
2125 end
2126
2127 if not(mod(i,handles.nsegments)+1 == currindex)
2128 handles.NextIndex = mod(i,handles.nsegments) + 1;
2129 handles=ConfigureClassSegment(handles);
2130 handles=ConfigureSpecPlot(handles);
2131 set(handles.ClassifyButton,'Enable','off');
2132 end
2133
2134 handles.lastsegment = currindex;
2135
2136
2137 function SkipButton_Callback(hObject, eventdata, handles)
2138
2139
2140
2141 handles = jump_to_unclassified(handles);
2142
2143 if handles.lastsegment == handles.NextIndex
2144 handles = quick_mode_exit(handles);
2145 set(handles.QuickModeButton,'Value',0);
2146 handles.quickmode = not(handles.quickmode);
2147 end
2148
2149 handles = configureclassview(handles,'select-class');
2150
2151 guidata(gcbo,handles);
2152
2153 function UndoButton_Callback(hObject, eventdata, handles)
2154
2155
2156
2157
2158 handles.NextIndex = handles.lastsegment;
2159 handles=ConfigureClassSegment(handles);
2160 handles=ConfigureSpecPlot(handles);
2161
2162 handles = quick_mode_exit(handles);
2163
2164 set(handles.QuickModeButton,'Value',0);
2165 handles.quickmode = not(handles.quickmode);
2166
2167 guidata(gcbo,handles);
2168
2169
2170 function NewQuickButton_Callback(hObject, eventdata, handles)
2171
2172
2173
2174
2175 handles = add_new_class(handles,handles.segments(handles.NextIndex));
2176 handles.segments(handles.NextIndex).class = handles.classes(handles.nclasses).name;
2177
2178 set(handles.ClassifyButton,'Enable','off');
2179
2180 handles = jump_to_unclassified(handles);
2181 handles = configureclassview(handles,'select-class');
2182
2183 if handles.lastsegment == handles.NextIndex
2184 handles = quick_mode_exit(handles)
2185 set(handles.QuickModeButton,'Value',0);
2186 handles.quickmode = not(handles.quickmode);
2187 end
2188
2189 guidata(gcbo,handles);
2190
2191
2192
2193
2194 function CompareToggleButton_Callback(hObject, eventdata, handles)
2195
2196
2197
2198
2199
2200
2201 state = get(hObject,'Value');
2202
2203 if handles.nclasses > 0
2204
2205 if state
2206 handles.mode = 'class-view';
2207 set(handles.RemoveClassButton,'Enable','off');
2208 set(handles.RenameClassButton,'Visible','off');
2209 set(handles.NextClassButton,'Visible','off');
2210 set(handles.ModePopupMenu,'Enable','off');
2211 set(handles.ClassifyButton,'Enable','off');
2212 set(handles.QuickModeButton,'Enable','off');
2213 set_status(handles,'Select a class to compare segment against');
2214 set(handles.NextSpectraButton,'Enable','off');
2215 set(handles.PreviousSpectraButton,'Enable','off');
2216 set(handles.TypifyClassButton, 'Visible', 'off');
2217 set(handles.AutoClassifyButton,'Enable','off');
2218
2219 handles = configureclassview(handles,'compare');
2220 else
2221 if strcmp(handles.mode,'comparison')
2222 set(hObject,'Value',1);
2223 handles.startx = 1;
2224 handles.endx = handles.classified_width;
2225
2226 set(handles.SliderClassified, 'Value',0);
2227 handles = configureclassview(handles,'compare');
2228 handles.mode = 'class-view';
2229 set_status(handles,'Select a class to compare segment against');
2230 elseif strcmp(handles.mode,'class-view')
2231 set_status(handles, ['Viewing all ', num2str(handles.nclasses),' classes']);
2232 set(handles.ModePopupMenu,'Enable','on');
2233 set(handles.QuickModeButton,'Enable','on');
2234 setnavigationbuttons(handles);
2235 SetModePopupMenu(handles,'class view');
2236 set(handles.RemoveClassButton,'Enable','on');
2237 set(handles.RemoveClassButton,'Visible','on');
2238 set(handles.ClassifyButton,'Enable','on');
2239 set(handles.AutoClassifyButton,'Enable','on');
2240 handles.submode = 'select';
2241 end
2242 end
2243
2244 else
2245 set(hObject,'Value',0);
2246 end
2247 guidata(hObject, handles);
2248
2249 function handles = recompute_classifiedaxes(handles)
2250
2251
2252
2253 classaxpos=get(handles.ClassifiedAxes,'Position');
2254
2255 set(handles.SliderClassified,'Value',0);
2256
2257 handles.startx = 1;
2258
2259 handles.classified_width = round(handles.classified_width_density * classaxpos(3));
2260 handles.classified_height = round(handles.classified_height_density * classaxpos(4));
2261
2262 oldpos = handles.startpage;
2263 handles = reposition_images(handles, handles.image_list);
2264
2265 cnrow = which_row(handles.positions,oldpos);
2266 for i = 1:(cnrow-1)
2267 handles = row_forward(handles);
2268 end
2269
2270 handles.cpositions = get_curr_position(handles);
2271 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
2272
2273 function reposy(guielement,deltay)
2274 oldpos = get(guielement,'Position');
2275 set(guielement,'Position',[oldpos(1), oldpos(2) + deltay, oldpos(3), oldpos(4)]);
2276
2277 function reposelementsy(handles,deltay)
2278 reposy(handles.PrecomputeButton,deltay);
2279 reposy(handles.DirectoryEditBox,deltay);
2280 reposy(handles.LoadDirectoryButton,deltay);
2281 reposy(handles.SaveButton,deltay);
2282 reposy(handles.ConfigureButton,deltay);
2283 reposy(handles.ViewText,deltay);
2284 reposy(handles.ModePopupMenu,deltay);
2285 reposy(handles.SegInfoText,deltay);
2286 reposy(handles.ToClassifyPanel,deltay);
2287 reposy(handles.NewQuickButton,deltay);
2288 reposy(handles.UndoButton,deltay);
2289 reposy(handles.SkipButton,deltay);
2290 reposy(handles.SortText,deltay);
2291 reposy(handles.SortPopupMenu,deltay);
2292 reposy(handles.NextClassButton,deltay);
2293
2294 function ResizeFcn(h, eventdata, handles, varargin)
2295
2296 handles = guidata(gcbo);
2297
2298 originalsize = handles.originalsize;
2299 newsize = get(h,'Position');
2300 classaxpos = get(handles.ClassifiedAxes,'Position');
2301
2302 if handles.originalsize(3) > newsize(3)
2303 newsize(3) = originalsize(3);
2304 classaxpos(3) = handles.originalaxessize(3);
2305
2306 sliderpos = get(handles.SliderClassified,'Position');
2307 sliderpos(3) = classaxpos(3);
2308 set(handles.SliderClassified,'Position',sliderpos);
2309
2310 else
2311 deltax = newsize(3) - handles.prevsize(3);
2312 classaxpos(3) = classaxpos(3) + deltax;
2313
2314 sliderpos = get(handles.SliderClassified,'Position');
2315 sliderpos(3) = sliderpos(3) + deltax;
2316 set(handles.SliderClassified,'Position',sliderpos);
2317
2318 end
2319
2320 if originalsize(4) > newsize(4)
2321 newsize(2) = newsize(2) + newsize(4) - originalsize(4);
2322
2323 deltay = originalsize(4) - handles.prevsize(4);
2324 newsize(4) = originalsize(4);
2325 classaxpos(4) = classaxpos(4) + newsize(4) - handles.prevsize(4);
2326 reposelementsy(handles,deltay);
2327
2328 else
2329 deltay = newsize(4) - handles.prevsize(4);
2330 reposelementsy(handles,deltay);
2331 classaxpos(4) = classaxpos(4) + newsize(4) - handles.prevsize(4);
2332 end
2333
2334 set(h,'Position',newsize);
2335 set(handles.ClassifiedAxes,'Position',classaxpos);
2336
2337 if handles.fixed || handles.blank
2338
2339 handles.classified_width_density = handles.classified_width / classaxpos(3);
2340 handles.classified_height_density = handles.classified_height / classaxpos(4);
2341 else
2342 handles = recompute_classifiedaxes(handles);
2343 end
2344
2345 handles.prevsize = newsize;
2346
2347 guidata(gcbo,handles);
2348
2349 function truth = truthrange(range)
2350 truth = range(1) && range (2);
2351
2352
2353 function ConfigureButton_Callback(hObject, eventdata, handles)
2354
2355
2356
2357
2358
2359 configs = configure_classify(handles.lowerfreq,handles.upperfreq,handles.classified_height,handles.classified_width,handles.Fs,handles.movingwin,handles.tapers,handles.fpass,handles.fixed);
2360 if not(isempty(configs) || length(configs) == 1)
2361 lowerfreq= configs{1};
2362 upperfreq= configs{2};
2363 classified_height= configs{3};
2364 classified_width= configs{4};
2365 Fs=configs{5};
2366 movingwin= configs{6};
2367 tapers= configs{7};
2368 fpass = configs{8};
2369
2370 rezoom = 0;
2371
2372 if not(handles.lowerfreq == lowerfreq)
2373 handles.lowerfreq = lowerfreq;
2374 rezoom = 1;
2375 end
2376
2377 if not(handles.upperfreq==upperfreq)
2378 handles.upperfreq=upperfreq;
2379 rezoom=1;
2380 end
2381
2382 redraw = 0;
2383 if not(handles.classified_height==classified_height)
2384 handles.classified_height=classified_height;
2385 redraw = 1;
2386 end
2387
2388 if not(handles.classified_width==classified_width)
2389 handles.classified_width=classified_height;
2390 redraw = 1;
2391 end
2392
2393 recompute = 0;
2394
2395 if not(handles.Fs==Fs)
2396 handles.Fs = Fs;
2397 recompute = 1;
2398 end
2399
2400 if not(truthrange(handles.movingwin == movingwin))
2401 handles.movingwin = movingwin;
2402 recompute = 1;
2403 end
2404
2405 if not(truthrange(handles.tapers==tapers))
2406 handles.tapers=tapers;
2407 recompute = 1;
2408 end
2409
2410 if not(truthrange(handles.fpass==fpass))
2411 handles.fpass=fpass;
2412 recompute = 1;
2413 end
2414
2415
2416 if recompute
2417 status = questdlg('Recompute spectra with changed parameters');
2418 if not(isempty(status))
2419 if strcmp(status,'Yes')
2420 handles = precompute_AllSpectra(handles);
2421 save_configuration(handles,handles.configfile);
2422
2423 handles=ConfigureSpecPlot(handles);
2424 set(handles.RemoveClassButton,'Visible','off');
2425 set(handles.TypifyClassButton, 'Visible', 'off');
2426 set(handles.NextClassButton,'Visible','off');
2427
2428 handles=BrowseDirectory(handles);
2429 set(handles.ModePopupMenu,'Value',1);
2430
2431 if handles.nclasses >= 1
2432 for j = 1:handles.nclasses
2433 handles.classes(j).iconS = handles.IconList{handles.classes(j).index};
2434 end
2435 end
2436
2437 set(handles.RemoveClassButton,'Visible','off');
2438 set(handles.TypifyClassButton, 'Visible', 'off');
2439 set(handles.NextClassButton,'Visible','off');
2440
2441 redraw = logical(1);
2442 end
2443 end
2444 end
2445
2446 if rezoom
2447 if strcmp(get(handles.ZoomButton,'String'),'Zoom out')
2448 handles.rezoom = logical(1);
2449 handles = ZoomSpectra(handles,'Zoom out');
2450 else
2451 handles.rezoom = logical(1);
2452 end
2453 end
2454
2455 if not(handles.configschanged)
2456 if not(recompute)
2457 handles.configschanged = logical(1);
2458 end
2459 end
2460
2461 if redraw
2462 classaxpos = get(handles.ClassifiedAxes,'Position');
2463 handles.classified_width_density = handles.classified_width / classaxpos(3);
2464 handles.classified_height_density = handles.classified_height / classaxpos(4);
2465 handles = recompute_classifiedaxes(handles);
2466 end
2467
2468 handles.fixed = configs{9};
2469
2470 end
2471 guidata(gcbo,handles);
2472
2473 function status = save_configuration(handles,filename)
2474
2475 Fs = handles.Fs;
2476 movingwin = handles.movingwin;
2477 tapers = handles.tapers;
2478 fpass = handles.fpass;
2479
2480 try
2481 save(filename,'Fs','movingwin','tapers','fpass','-mat');
2482 catch
2483 status = 1;
2484 end
2485
2486 function handles = load_configuration(handles,filename)
2487 try
2488 load('-mat',filename)
2489 if handles.Fs == Fs || handles.movingwin == movingwin || handles.tapers == tapers || handles.fpass == fpass
2490 handles.configshavechanged = logical(1);
2491 end
2492
2493 handles.Fs = Fs;
2494 handles.movingwin = movingwin;
2495 handles.tapers = tapers;
2496 handles.fpass = fpass;
2497 catch
2498 handles = handles;
2499 end
2500
2501
2502
2503 function NextClassButton_Callback(hObject, eventdata, handles)
2504
2505
2506
2507
2508 handles.lastclass = handles.lastclass + 1;
2509
2510 if handles.lastclass > handles.nclasses
2511 handles.lastclass = 1;
2512 end
2513
2514 class = handles.classes(handles.lastclass);
2515 handles = configureclassmembers(handles,class.name);
2516 set_status(handles,['Viewing ' num2str(length(handles.mapindex)) ' members of ' class.name]);
2517 handles.mode = 'class-members';
2518 handles.submode = 'select';
2519
2520 guidata(gcbo,handles);
2521
2522 function handles = features_segments(handles)
2523
2524 h=waitbar(0,'Computing Data Features. . . ');
2525 for i = 1:handles.nsegments
2526 startf = handles.segments(i).start;
2527 endf = handles.segments(i).end;
2528 cepestral = cepsfromspectra(handles.segments(i).specfilename,handles.ncepestral);
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539 waitbar(i/handles.nsegments);
2540
2541 handles.segments(i).features = cepestral';
2542
2543
2544
2545
2546
2547
2548 end
2549 close(h);
2550
2551 function coefs = cepsfromspectra(specfilename,ncepestral)
2552 load('-mat',specfilename);
2553 sbase = (mean(min(exp(Spre))) + mean(min(exp(Spost)))) / 2;
2554
2555
2556
2557
2558
2559
2560
2561
2562 Sdiff = exp(S) - sbase;
2563 spectra = log(mean(Sdiff'));
2564
2565
2566
2567 cepstrum = real(ifft(spectra));
2568
2569
2570
2571
2572
2573 coefs = cepstrum(1:ncepestral);
2574
2575
2576 function classifymatrix = generate_classify_mat(handles)
2577 classifymatrix = zeros(handles.nsegments,handles.nfeatures+1);
2578 for i = 1:handles.nsegments
2579 seglength = handles.segments(i).end - handles.segments(i).start;
2580 classifymatrix(i,1:1+handles.nfeatures) = [seglength handles.segments(i).features(1:handles.nfeatures)'];
2581 end
2582 ;
2583
2584 function handles = generate_classes_auto(handles,classification)
2585 nclasses = length(unique(classification));
2586 classesfound = zeros(nclasses,1);
2587 handles.classes = [];
2588 handles.nclasses = 0;
2589 j = 1;
2590 for i = 1:handles.nsegments
2591 if classification(i) == 0
2592 handles.segments(i).class = '';
2593 else
2594 if isempty(classesfound(find(classesfound == classification(i))))
2595 class.specfilename = handles.segments(i).specfilename;
2596 class.name = newclassname(handles);
2597 class.index = i;
2598 class.length = handles.segments(i).end - handles.segments(i).start;
2599 class.iconS = handles.IconList{i};
2600 class.nmembers = 1;
2601 handles.segments(i).class = class.name;
2602 handles.classes = [handles.classes class];
2603 classesfound(j) = classification(i);
2604 j = j + 1;
2605 handles.nclasses = handles.nclasses + 1;
2606 else
2607 classindex = find(classification(i) == classesfound);
2608 handles.segments(i).class = handles.classes(classindex).name;
2609 handles.classes(classindex).nmembers = handles.classes(classindex).nmembers + 1;
2610 end
2611 end
2612 end
2613 ;
2614
2615
2616 function AutoClassifyButton_Callback(hObject, eventdata, handles)
2617
2618
2619
2620
2621 if length(handles.segments(1).features) == 0;
2622 handles = features_segments(handles);
2623 end
2624
2625 matrix2classify = generate_classify_mat(handles);
2626
2627 classification = auto_classify(matrix2classify,handles.nfeatures);
2628
2629 if length(classification) > 1
2630 if not(isempty(handles.classes))
2631 answer = questdlg('A classification already exists. Do you want to replace the current classification?');
2632 if strcmp(answer,'Yes')
2633 handles = generate_classes_auto(handles,classification);
2634 end
2635 else
2636 handles = generate_classes_auto(handles,classification);
2637
2638 end
2639
2640 handles=configureclassview(handles,'select');
2641 set(handles.ClassifyButton,'String','Declassify');
2642 set(handles.RemoveClassButton,'Visible','on');
2643 set(handles.RemoveClassButton,'Enable','on');
2644 set(handles.CompareToggleButton,'Visible','on');
2645 set(handles.CompareToggleButton,'Enable','on');
2646 set(handles.TypifyClassButton, 'Visible', 'off');
2647 set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes'])
2648
2649
2650
2651
2652
2653
2654
2655 end
2656 guidata(gcbo,handles);
2657
2658
2659
2660 function FileMenu_Callback(hObject, eventdata, handles)
2661
2662
2663
2664
2665
2666
2667 function SaveItem_Callback(hObject, eventdata, handles)
2668
2669
2670
2671
2672 SaveButton_Callback(hObject, eventdata, handles)
2673
2674
2675 function LoadItem_Callback(hObject, eventdata, handles)
2676
2677
2678
2679
2680 PrecomputeButton_Callback(hObject, eventdata, handles)
2681
2682
2683
2684
2685 function HelpMenu_Callback(hObject, eventdata, handles)
2686
2687
2688
2689
2690
2691
2692 function HelpItem_Callback(hObject, eventdata, handles)
2693
2694
2695
2696
2697 web('classify_spectra_help.html');
2698
2699
2700 function AboutItem_Callback(hObject, eventdata, handles)
2701
2702
2703
2704
2705 msgbox('Classify_spectra (version 0.2) is being developed by the Mitra Lab at the Cold Spring Harbor Laboratory.','About classify_spectra');
2706
2707
2708
2709 function ConfigureItem_Callback(hObject, eventdata, handles)
2710
2711
2712
2713
2714 ConfigureButton_Callback(hObject, eventdata, handles)
2715
2716 function coefs = cepcoefs(data,p)
2717
2718 coefs = [];
2719 if p > 0
2720 y = fft(hamming(length(data)) .* data);
2721 coefs = aryule(ifft(log(abs(y))),p);
2722 end
2723
2724 function generate_output(handles,absolutetime,filename);
2725
2726 filebasetosave = filename(1:length(filename)-4);
2727
2728 matrixoutput = cell(handles.nsegments,1);
2729
2730 for i = 1:handles.nsegments
2731 segment = handles.segments(i);
2732
2733 if absolutetime
2734 dstr = regexp(segment.wavfile,'[0-9]+\-[0-9]+\-[0-9]+','match');
2735 dstr = dstr{1};
2736 tstr = regexp(segment.wavfile,'[0-9][0-9][0-9][0-9][0-9][0-9]','match');
2737 tstr = tstr{1};
2738 tstr = [tstr(1:2) ':' tstr(3:4) ':' tstr(5:6)];
2739 segmentstart = datenum([dstr ' ' tstr]) + segment.start;
2740 segmentstart = datevec(segmentstart);
2741 else
2742 segmentstart = segment.start;
2743 end
2744 matrixoutput{i} = {segment.wavfile,segment.class,segmentstart,segment.end - segment.start,segment.features};
2745 end
2746
2747 save([filebasetosave '.mat'],'-mat','matrixoutput','-mat');
2748
2749 delimiter = '\t';
2750 fp = fopen([filebasetosave '.txt'],'wt');
2751
2752
2753
2754 fprintf(fp,'filename');fprintf(fp,delimiter);
2755 fprintf(fp,'class');fprintf(fp,delimiter);
2756
2757 if absolutetime
2758 fprintf(fp,'year');fprintf(fp,delimiter);
2759 fprintf(fp,'month');fprintf(fp,delimiter);
2760 fprintf(fp,'day');fprintf(fp,delimiter);
2761 fprintf(fp,'hour');fprintf(fp,delimiter);
2762 fprintf(fp,'minute');fprintf(fp,delimiter);
2763 fprintf(fp,'second');fprintf(fp,delimiter);
2764 else
2765 fprintf(fp,'start');fprintf(fp,delimiter);
2766 end
2767
2768 fprintf(fp,'length');fprintf(fp,delimiter);
2769
2770 for i = 1:handles.nfeatures
2771 fprintf(fp,['d' num2str(i)]);
2772 if i < handles.nfeatures;
2773 fprintf(fp,delimiter);
2774 else
2775 fprintf(fp,'\n');
2776 end
2777 end
2778
2779
2780
2781
2782 for i = 1:handles.nsegments
2783 segment = handles.segments(i);
2784 fprintf(fp,['"' segment.wavfile '"']);fprintf(fp,delimiter);
2785 fprintf(fp,['"' segment.class '"']);fprintf(fp,delimiter);
2786
2787 if absolutetime
2788 time = matrixoutput{i}{3};
2789
2790 fprintf(fp,num2str(time(1)));fprintf(fp,delimiter);
2791 fprintf(fp,num2str(time(2)));fprintf(fp,delimiter);
2792 fprintf(fp,num2str(time(3)));fprintf(fp,delimiter);
2793 fprintf(fp,num2str(time(4)));fprintf(fp,delimiter);
2794 fprintf(fp,num2str(time(5)));fprintf(fp,delimiter);
2795 fprintf(fp,num2str(time(6)));
2796
2797 else
2798 fprintf(fp,num2str(segment.start));
2799 end
2800
2801 fprintf(fp,delimiter);
2802 fprintf(fp,num2str(segment.end-segment.start));fprintf(fp,delimiter);
2803
2804 for j = 1:handles.nfeatures
2805 fprintf(fp,num2str(segment.features(j)));
2806 if j < handles.nfeatures
2807 fprintf(fp,delimiter);
2808 else
2809 if i < handles.nsegments
2810 fprintf(fp,'\n');
2811 end
2812 end
2813 end
2814 end
2815 fclose(fp);
2816
2817 function ExportDataItem_Callback(hObject, eventdata, handles)
2818
2819
2820
2821
2822 filename = uiputfile('*.txt','File to write exported data to');
2823
2824 if not(filename == 0)
2825 if length(handles.segments(1).features) == 0
2826 handles = features_segments(handles);
2827 end
2828 generate_output(handles,1,filename);
2829 end
2830
2831
2832
2833 function CleanDirectoryItem_Callback(hObject, eventdata, handles)
2834
2835
2836
2837
2838 answer = questdlg('Clean the current directory. This will remove all files generated by classify_spectra including the file which includes the classification');
2839 if strcmp(answer,'Yes');
2840 specfiles = dir('*.spec');
2841
2842 for i = 1:length(specfiles)
2843 delete(specfiles(i).name);
2844 end
2845
2846
2847 if exist('class_spec.conf')
2848 delete('class_spec.conf');
2849 end
2850
2851 if exist([handles.baseclassname '.dat'])
2852 delete([handles.baseclassname '.dat']);
2853 end
2854
2855
2856 end