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 gui_Singleton = 1;
0029 gui_State = struct('gui_Name', mfilename, ...
0030 'gui_Singleton', gui_Singleton, ...
0031 'gui_OpeningFcn', @classify_spectra_OpeningFcn, ...
0032 'gui_OutputFcn', @classify_spectra_OutputFcn, ...
0033 'gui_LayoutFcn', [] , ...
0034 'gui_Callback', []);
0035 if nargin & isstr(varargin{1})
0036 gui_State.gui_Callback = str2func(varargin{1});
0037 end
0038
0039 if nargout
0040 [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
0041 else
0042 gui_mainfcn(gui_State, varargin{:});
0043 end
0044
0045
0046
0047 function classify_spectra_OpeningFcn(hObject, eventdata, handles, varargin)
0048
0049
0050
0051
0052
0053
0054
0055 handles.output = hObject;
0056
0057
0058 handles.recompute = logical(1);
0059 handles.cwavfile = '';
0060
0061 handles.directory = pwd;
0062
0063 handles.ispecheight = 100;
0064 handles.ismaxwidth = 340;
0065 handles.specpad = 0.02;
0066
0067 handles.Fs = 44100;
0068 handles.movingwin=[0.01 0.002];
0069 handles.tapers=[3 5];
0070 handles.pad=1;
0071 handles.fpass=[0 20000];
0072
0073 handles.nsegments = 0;
0074 handles.NextIndex = 1;
0075 handles.maxseglength = 0;
0076
0077
0078
0079 handles.classified_height = 605;
0080 handles.classified_width = 450;
0081
0082 handles.xspacer = 5;
0083 handles.yspacer = 20;
0084
0085 handles.image_list = {};
0086 handles.positions = [];
0087 handles.images_dim = [];
0088
0089 handles.mapindex = [];
0090
0091 handles.nimages = 0;
0092 handles.number_rows = floor(handles.classified_height/(handles.yspacer + handles.ispecheight));
0093
0094 handles.cnrows = 0;
0095
0096 handles.startpage = 1;
0097 handles.endpage = 1;
0098
0099 handles.mode = 'browse';
0100
0101
0102 handles.submode = 'select';
0103
0104
0105 handles.quickmode = logical(0);
0106
0107
0108
0109 handles.baseclassname = 'mockingbird';
0110
0111
0112 handles.nclasses = 0;
0113 handles.classes = [];
0114
0115
0116 guidata(hObject, handles);
0117
0118
0119
0120
0121
0122 function varargout = classify_spectra_OutputFcn(hObject, eventdata, handles)
0123
0124
0125
0126
0127
0128
0129 varargout{1} = handles.output;
0130
0131 function DirectoryEditBox_Callback(hObject, eventdata, handles)
0132 handles.directory = get(hObject,'String');
0133
0134 function DirectoryEditBox_CreateFcn(hObject, eventdata, handles)
0135 set(hObject,'string',pwd);
0136 guidata(gcbo,handles);
0137 if ispc
0138 set(hObject,'BackgroundColor','white');
0139 else
0140 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
0141 end
0142
0143
0144
0145
0146
0147 function segments=LoadSegmentsFromDirectory(directory)
0148 segfilelist = dir( [directory '\*' '.seg.txt'] );
0149
0150 nsegfile = length(segfilelist);
0151 segments = [];
0152 n = 1;
0153 while n <= nsegfile
0154 segfilename = segfilelist(n).name;
0155 fid=fopen( segfilename, 'r' );
0156 if fid ~= -1
0157 scanned=fscanf( fid, '%g %g',[2 inf] );
0158 fclose(fid);
0159
0160 wavfile = segfilename(1:(length(segfilename)-8));
0161 i = 1;
0162 while i <= size(scanned, 2)
0163 segment.wavfile = wavfile;
0164 segment.class = '';
0165 segment.start = scanned(1,i);
0166 segment.end = scanned(2,i);
0167 segment.specfilename = [segment.wavfile '.' num2str(segment.start) '-' num2str(segment.end) '.spec'];
0168 segments = [ segment segments ];
0169 i = i + 1;
0170 end
0171 end
0172 n = n + 1;
0173 end
0174
0175 function handles=Load_InitialSegments(hObject,handles)
0176
0177 handles.segments = LoadSegmentsFromDirectory(handles.directory);
0178 handles.nsegments = length(handles.segments);
0179 guidata(hObject, handles);
0180
0181
0182
0183
0184
0185 function handles = cindex2imagelist(handles)
0186
0187 handles.image_list = {};
0188
0189 for i = 1:length(handles.mapindex)
0190 handles.image_list{i} = handles.classes( handles.mapindex(i) ).iconS;
0191 end
0192
0193 function mapindex = sortindexbypop(handles)
0194
0195 nindexes = length(handles.mapindex);
0196 mapindex = [];
0197 for i = 1:nindexes
0198 mapindex(i,1:2) = [handles.mapindex(i) handles.classes(handles.mapindex(i)).nmembers];
0199 end
0200 mapindex = sortrows(mapindex, 2);
0201 mapindex = flipud(mapindex(:,1));
0202
0203 function class_string = newclassname(handles)
0204
0205
0206
0207 nbaseclass = length(handles.baseclassname);
0208 classnum = 0;
0209 for i = 1:handles.nclasses
0210 classname = handles.classes(i).name;
0211 curr_classnum = str2num(classname(nbaseclass + 1:length(classname)));
0212 if curr_classnum > classnum
0213 classnum = curr_classnum;
0214 end
0215 end
0216 class_string = strcat(handles.baseclassname,num2str(classnum + 1));
0217 ;
0218
0219 function cindex = returnclassindex(handles,classname)
0220
0221 cindex = 0;
0222 i = 1;
0223 while (i <= handles.nclasses) && not(strcmp(classname,handles.classes(i).name))
0224 i = i + 1;
0225 end
0226 cindex = i;
0227 ;
0228
0229 function handles = add_new_class(handles,segment)
0230
0231 handles.nclasses = length(handles.classes);
0232 class.name = newclassname(handles);
0233 class.nmembers = 1;
0234 class.specfilename = segment.specfilename;
0235 load('-mat',class.specfilename);
0236 class.iconS = iconS;
0237 class.length = segment.end - segment.start;
0238
0239 handles.classes = [handles.classes class];
0240 handles.nclasses = handles.nclasses + 1;
0241
0242 ;
0243
0244 function handles=ConfigureClassSegment(handles)
0245
0246 segment = handles.segments(handles.NextIndex);
0247 if strcmp(segment.class,'')
0248 set(handles.ClassifyButton,'String','Classify');
0249 set(handles.ClassifyButton,'Enable','on');
0250 else
0251 set(handles.ClassifyButton,'String','Declassify');
0252 set(handles.ClassifyButton,'Enable','on');
0253 end
0254
0255
0256
0257 function ClassifyButton_Callback(hObject, eventdata, handles)
0258
0259
0260
0261
0262 status = get(handles.ClassifyButton,'String');
0263 set(handles.TypifyClassButton,'Visible', 'off');
0264 set(handles.RemoveClassButton, 'Visible', 'off');
0265 if strcmp(status,'Classify')
0266 set_status(handles,'');
0267 set(handles.NextSpectraButton,'Enable','off');
0268 set(handles.PreviousSpectraButton,'Enable','off');
0269 set(handles.ClassifyButton,'Enable','off');
0270 set(handles.NewClassButton,'Visible','on');
0271
0272 if handles.nclasses > 0
0273 handles = configureclassview(handles,'select-class');
0274 else
0275 axes(handles.ClassifiedAxes);
0276 handles.hiclass = image(uint8(zeros(handles.classified_height,handles.classified_width)));
0277 handles.mode = 'class-view';
0278 handles.submode = 'select-class';
0279 set(handles.hiclass,'ButtonDownFcn',{@DummyClassifyAxesClickCallBack,handles});
0280 end
0281
0282 handles = SetModePopupMenu(handles,'class view');
0283 set(handles.ModePopupMenu,'Enable','off');
0284 elseif strcmp(status,'Declassify')
0285 cindex = returnclassindex(handles,handles.segments(handles.NextIndex).class);
0286 if handles.classes(cindex).nmembers == 1
0287 if length(handles.classes) == 1
0288 axes(handles.ClassifiedAxes);
0289 handles.classes = [];
0290 handles.nclasses = 0;
0291 handles.hiclass = image(uint8(zeros(handles.classified_height,handles.classified_width)));
0292 else
0293 handles.classes = [handles.classes(1:cindex-1) handles.classes(cindex + 1:length(handles.classes))];
0294 handles.nclasses = handles.nclasses - 1;
0295 end
0296 else
0297 if strcmp(handles.classes(cindex).specfilename,handles.segments(handles.NextIndex).specfilename)
0298 i = 1;
0299 segs = [ handles.segments(1:(handles.NextIndex - 1)) handles.segments((handles.NextIndex + 1) : handles.nclasses)];
0300 while (i <= length(segs)) && strcmp(segs(i).class,handles.classes(cindex).name)
0301 i = i + 1;
0302 end
0303 handles.classes(cindex).specfilename = handles.segments(i).specfilename;
0304 handles.classes(cindex).length = handles.segments(i).end - handles.segments(i).start;
0305 load('-mat', 'specicons');
0306 handles.iconS = IconList{i};
0307 end
0308 handles.classes(cindex).nmembers = handles.classes(cindex).nmembers - 1;
0309
0310
0311 end
0312 if handles.nclasses >= 1
0313 handles = configureclassview(handles,'select');
0314 end
0315 set(handles.ClassifyButton,'String','Classify');
0316 handles.segments(handles.NextIndex).class = '';
0317 set_status(handles,'');
0318 setnavigationbuttons(handles);
0319 end
0320 guidata(gcbo,handles);
0321
0322
0323
0324 function NewClassButton_Callback(hObject, eventdata, handles)
0325
0326
0327
0328
0329 handles = add_new_class(handles,handles.segments(handles.NextIndex));
0330 handles.segments(handles.NextIndex).class = handles.classes(handles.nclasses).name;
0331
0332 set(handles.ClassifyButton,'Enable','on');
0333 set(handles.ClassifyButton,'String','Declassify');
0334 set(handles.NewClassButton,'Visible','off');
0335 set(handles.ModePopupMenu,'Enable','on');
0336 set(handles.NextSpectraButton,'Enable','on');
0337 set(handles.PreviousSpectraButton,'Enable','on');
0338 handles = configureclassview(handles,'xxx');
0339 setnavigationbuttons(handles);
0340 set_status(handles,'');
0341 handles = SetModePopupMenu(handles,'class view');
0342 guidata(gcbo,handles);
0343 ;
0344
0345
0346 function RemoveClassButton_Callback(hObject, eventdata, handles)
0347
0348
0349
0350
0351
0352 set(handles.RemoveClassButton,'Enable','off');
0353 handles.mode = 'class-view';
0354 handles.submode = 'remove-class';
0355 guidata(gcbo,handles);
0356
0357
0358
0359 function TypifyClassButton_Callback(hObject, eventdata, handles)
0360
0361
0362
0363
0364 set(handles.TypifyClassButton,'Enable','off');
0365
0366 handles.mode = 'class-members';
0367 handles.submode = 'typify';
0368 set_status(handles,'Select an icon to change the type');
0369 guidata(gcbo,handles);
0370
0371
0372
0373
0374
0375 function segment=precompute_spectra(handles, segment)
0376
0377 spec_ipad = round(handles.specpad * handles.Fs);
0378 spec_istart = round(segment.start * handles.Fs);
0379 spec_iend = round(segment.end * handles.Fs);
0380
0381
0382 try
0383 [data] = wavread(segment.wavfile, [spec_istart - spec_ipad, spec_iend + spec_ipad]);
0384 catch
0385 errmsg = lasterr;
0386 if strfind(errmsg, 'Sample limits out of range')
0387 if (segment.start - handles.specpad) < 0
0388 [data] = wavread(segment.wavfile, [1 spec_iend + spec_ipad]);
0389 else
0390 [data] = wavread(segment.wavfile);
0391 [data] = data((spec_istart - spec_ipad):length(data));
0392 end
0393 end
0394 end
0395
0396 [Sfull tfull f] = compute_spectra(data,handles.tapers,handles.Fs,handles.fpass,handles.movingwin);
0397
0398 wavlength = length(data);
0399 Ssize = size(Sfull);
0400
0401 Slength = Ssize(2);
0402 RatioWS = Slength / (wavlength / handles.Fs);
0403
0404 Sstart = round(RatioWS * segment.start);
0405 Send = round(RatioWS * segment.end);
0406 Spad = round(RatioWS * handles.specpad);
0407
0408 Spre = Sfull(:,1:Spad);
0409 S = Sfull(:,Spad+1:Spad + Send-Sstart);
0410 Spost = Sfull(:,Spad + (Send-Sstart)+1:Slength);
0411 t=[segment.start, segment.end];
0412
0413 iconS = iconify_spec(S,handles.ispecheight);
0414
0415 save(segment.specfilename,'S','t','f','Spre','Spost','tfull','iconS','-mat');
0416
0417 fprintf('Saving %s file\n',segment.specfilename);
0418
0419 function handles = precompute_AllSpectra(handles)
0420
0421 hw = waitbar(0,'Precomputing spectra. . .');
0422 if handles.nsegments >= 1
0423 for i = 1:handles.nsegments
0424 precompute_spectra(handles,handles.segments(i));
0425 waitbar(i/handles.nsegments);
0426 end
0427 end
0428 close(hw);
0429 get_SpecIcons(handles);
0430 ;
0431 function [S t f]=compute_spectra(data,tapers,Fs,fpass,movingwin)
0432 params.tapers=tapers; params.Fs=Fs; params.fpass=fpass;
0433 [S t f] = mtspecgramc( diff(data), movingwin, params );
0434 S = log(S)';
0435
0436
0437
0438
0439
0440
0441 function handles=get_and_plot(hObject, handles, segment)
0442 load('-mat',segment.specfilename);
0443 axes(handles.ToClassifyAxes);
0444
0445 cmap = jet(256);
0446 cmap(1,:) = [1, 1, 1];
0447 colormap(cmap);
0448 SFull = cat(2,Spre,S,Spost);
0449 SFmin = min(min(SFull));
0450 SFmax = max(max(SFull));
0451 SFull = uint8(1 + round(255 * (SFull-SFmin) / (SFmax-SFmin)));
0452
0453 image(tfull + segment.start - handles.specpad,f,SFull);
0454
0455 hline1 = line([segment.start segment.start],[f(1) max(f)],'Color',[0 0 0],'LineWidth',3);
0456 hline2 = line([segment.end segment.end],[f(1),max(f)],'Color',[0 0 0],'LineWidth',3);
0457 axis xy;
0458 axes(handles.ToClassifySmallAxes);
0459 ispecFull = uint8(zeros(handles.ispecheight,handles.ismaxwidth));
0460 ispecFull = copy_into(ispecFull,iconS,1,1);
0461
0462 ih = image(ispecFull);
0463 ;
0464
0465 function handles=ConfigureSpecPlot(hObject,handles)
0466
0467 segment = handles.segments(handles.NextIndex);
0468 if not(exist(segment.specfilename)) || handles.recompute
0469 precompute_spectra(handles,segment);
0470 end
0471 set(handles.CurrentFilenameEdit,'String',segment.wavfile);
0472 handles=get_and_plot(hObject, handles, segment);
0473 guidata(gcbo,handles);
0474 ;
0475
0476 function NextSpectraButton_Callback(hObject, eventdata, handles)
0477
0478 handles.NextIndex = handles.NextIndex + 1;
0479 if handles.NextIndex == handles.nsegments
0480 set(handles.NextSpectraButton,'Enable','off');
0481 end
0482
0483 if handles.NextIndex > 1
0484 set(handles.PreviousSpectraButton,'Enable','on');
0485 end
0486
0487 handles=ConfigureClassSegment(handles);
0488 handles=ConfigureSpecPlot(hObject,handles);
0489 guidata(gcbo,handles);
0490 ;
0491
0492 function PreviousSpectraButton_Callback(hObject, eventdata, handles)
0493
0494 handles.NextIndex = handles.NextIndex - 1;
0495
0496 if handles.NextIndex == 1
0497 set(handles.PreviousSpectraButton,'Enable','off');
0498 set(handles.NextSpectraButton,'Enable','on');
0499 end
0500
0501 if handles.NextIndex < handles.nsegments
0502 set(handles.NextSpectraButton,'Enable','on');
0503 end
0504
0505 handles=ConfigureClassSegment(handles);
0506 handles=ConfigureSpecPlot(hObject,handles);
0507
0508 set(handles.NextSpectraButton,'Enable','off');
0509 set(handles.NextSpectraButton,'Enable','on');
0510 guidata(gcbo,handles);
0511 ;
0512
0513 function PrecomputeButton_Callback(hObject, eventdata, handles)
0514
0515
0516 handles.directory = get(handles.DirectoryEditBox,'String');
0517
0518
0519
0520
0521 handles.classes = [];
0522 set( handles.PrecomputeButton, 'Enable', 'off' );
0523 handles.NextIndex = 1;
0524
0525 handles = Load_InitialSegments(hObject,handles);
0526 handles.recompute = logical(0);
0527
0528
0529 if handles.nsegments >= 1
0530 handles=ConfigureClassSegment(handles);
0531
0532 if exist([handles.baseclassname '.dat'])
0533 data = read_syllable_database(handles);
0534 handles = merge_syllable_database(handles,data);
0535 else
0536 handles = precompute_AllSpectra(handles);
0537 end
0538
0539 handles=ConfigureSpecPlot(hObject,handles);
0540 handles=BrowseDirectory(handles);
0541 set(handles.PlaySegmentButton, 'Enable', 'on' );
0542 set(handles.NextSpectraButton, 'Enable', 'on' );
0543 set(handles.NextRowButton, 'Enable', 'on' );
0544 set(handles.PreviousRowButton, 'Enable', 'on' );
0545 set(handles.ModePopupMenu,'Enable','on');
0546 set(handles.SaveButton,'Enable','on');
0547 set( handles.PrecomputeButton, 'Enable', 'off' );
0548 end
0549 guidata(gcbo,handles);
0550 ;
0551
0552
0553
0554 function PlaySegmentButton_Callback(hObject, eventdata, handles)
0555
0556
0557
0558
0559 segment = handles.segments(handles.NextIndex);
0560 data = wavread(segment.wavfile,[round(handles.Fs * segment.start),round(handles.Fs * segment.end)]);
0561 wavplay(data,handles.Fs);
0562
0563
0564 function CurrentFilenameEdit_Callback(hObject, eventdata, handles)
0565
0566 function CurrentFilenameEdit_CreateFcn(hObject, eventdata, handles)
0567 if ispc
0568 set(hObject,'BackgroundColor','white');
0569 else
0570 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
0571 end
0572
0573
0574
0575
0576
0577
0578 function iconS = iconify_spec(S,height)
0579
0580
0581 Ssize = size(S);
0582 iconS = zeros(height,Ssize(2));
0583
0584
0585 rf = floor(Ssize(1)/height);
0586
0587 for i = 1:(height-1)
0588 for j = 1 : Ssize(2)
0589 iconS(i,j) = mean(S(((i-1)*rf)+1:i*rf,j));
0590 end
0591 end
0592
0593 for j = 1 : Ssize(2)
0594 iconS(height,j) = mean(S(rf*(height-1) : Ssize(1),j));
0595 end
0596 iconS = flipud(iconS);
0597
0598
0599 maxintense = max(max(iconS));
0600 minintense = min(min(iconS));
0601
0602 iconS=uint8(1 + round(255 * (iconS-minintense)/(maxintense-minintense)));
0603
0604
0605
0606
0607
0608 function destination = copy_into(destination,source,r,c)
0609
0610
0611
0612 sized = size(destination);
0613 sizes = size(source);
0614 for i = 1:sizes(1)
0615 for j = 1:sizes(2)
0616 destination(r+i,c+j) = source(i,j);
0617 end
0618 end
0619 ;
0620
0621 function positions = position_images(height,width,images_dim,xspacer,yspacer)
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634 number_images = length(images_dim(:,1));
0635 imageheight = images_dim(1);
0636
0637 currentx = xspacer;
0638 currenty = yspacer;
0639
0640 positions = zeros(number_images,2);
0641
0642 for i = 1:number_images
0643 if (currentx + images_dim(i,2) + xspacer) > width
0644 currentx = xspacer;
0645 currenty = currenty + imageheight + yspacer;
0646 positions(i,:) = [currenty currentx];
0647 currentx = currentx + images_dim(i,2) + xspacer;
0648 else
0649 positions(i,:) = [currenty currentx];
0650 currentx = currentx + images_dim(i,2) + xspacer;
0651 end
0652
0653 end
0654
0655 function image_matrix = place_images_into(image_matrix, image_list, position_list)
0656
0657 number_images = length(image_list);
0658
0659 for i = 1:number_images
0660 theimage = image_list{i};
0661 image_matrix = copy_into(image_matrix, theimage, position_list(i,1), position_list(i,2));
0662 end
0663 ;
0664
0665 function image_dim = get_image_sizes(images)
0666
0667 number_images = length(images);
0668 image_dim = zeros(number_images,2);
0669 for i = 1:number_images
0670 image_dim(i,:) = size(images{i});
0671 end
0672 ;
0673
0674 function image_matrix = place_images_into(image_matrix, image_list, position_list)
0675
0676 number_images = length(image_list);
0677
0678 for i = 1:number_images
0679 theimage = image_list{i};
0680 image_matrix = copy_into(image_matrix, theimage, position_list(i,1), position_list(i,2));
0681 end
0682 ;
0683
0684
0685
0686
0687
0688 function IconList=get_SpecIcons(handles)
0689 IconList = {};
0690 status = 0;
0691 for i = 1:handles.nsegments
0692 load('-mat',handles.segments(i).specfilename);
0693 IconList{i} = iconS;
0694 end
0695 save('specicons','IconList','-mat');
0696
0697
0698 function handles = plot_classified_axes(handles, image_list, position_list)
0699
0700 classmatrix = uint8(zeros(handles.classified_height,handles.classified_width));
0701 axes(handles.ClassifiedAxes);
0702 classmatrix = place_images_into(classmatrix,image_list,position_list);
0703 handles.hiclass = image(classmatrix);
0704 set(handles.hiclass,'ButtonDownFcn',{@ClassifyAxesClickCallBack});
0705
0706
0707 function handles = reposition_images(handles, image_list)
0708
0709
0710
0711
0712
0713 handles.nimages = length(image_list);
0714 handles.images_dim = get_image_sizes(image_list);
0715
0716 handles.positions = position_images(handles.classified_height,handles.classified_width,handles.images_dim,handles.xspacer,handles.yspacer);
0717 handles.cnrows = length(unique(handles.positions(:,1)));
0718
0719 handles.numberofrows = floor(handles.classified_height / (handles.ispecheight + handles.yspacer));
0720 handles.startpage = 1;
0721 handles.endpage = 1;
0722
0723 for i = 1 : handles.numberofrows
0724 handles.endpage = next_row_end(handles.positions,handles.endpage);
0725 end
0726
0727 ;
0728
0729 function cpositions = get_curr_position(handles)
0730
0731 cpositions = handles.positions(handles.startpage:handles.endpage,:);
0732 cpositions(:,1) = cpositions(:,1) - cpositions(1,1) + handles.yspacer;
0733 ;
0734
0735 function cposition = next_row_start(positions,cposition)
0736
0737
0738 npos = length(positions);
0739 i = cposition;
0740 while (i <= npos) && positions(i,1) == positions(cposition,1)
0741 i = i + 1;
0742 end
0743 if i < npos
0744 cposition = i;
0745 end
0746 ;
0747
0748 function cposition = next_row_end(positions,cposition)
0749
0750
0751 npos = length(positions(:,1));
0752 if cposition < npos
0753 i = cposition + 1;
0754 while (i < npos) && (positions(i,1) == positions(cposition+1,1))
0755 i = i + 1;
0756 end
0757 if (positions(cposition + 1) == positions(npos))
0758 cposition = npos;
0759 else
0760 cposition = i - 1;
0761
0762 end
0763 else
0764 cposition = npos;
0765 end
0766 ;
0767
0768
0769 function handles = row_forward(handles)
0770
0771 startpage = next_row_start(handles.positions,handles.startpage);
0772 endpage = next_row_end(handles.positions,handles.endpage);
0773
0774 if endpage ~ handles.endpage
0775 handles.startpage = startpage;
0776 handles.endpage = endpage;
0777 end
0778
0779 ;
0780
0781 function cposition = previous_row_start(positions,cposition)
0782
0783
0784 npos = length(positions(:,1));
0785
0786 if cposition > 1
0787 i = cposition - 1;
0788 while (i > 1) && (positions(i,1) == positions(cposition-1,1))
0789 i = i - 1;
0790 end
0791 if i > 1
0792 cposition = i + 1;
0793 else
0794 cposition = 1;
0795 end
0796 else
0797 cposition = 1;
0798 end
0799 ;
0800
0801 function cposition = previous_row_end(positions,cposition)
0802 npos = length(positions(:,1));
0803
0804 if cposition > 1
0805 i = cposition;
0806 while (i > 1) && (positions(i,1) == positions(cposition,1))
0807 i = i - 1;
0808 end
0809 if i > 1;
0810 cposition = i;
0811 else
0812 cposition = 1;
0813 end
0814 else
0815 cposition = 1;
0816 end
0817 ;
0818
0819 function nrows = number_of_rows(handles)
0820
0821 nrows = length(unique(handles.positions(handles.startpage:handles.endpage,1)));
0822
0823 function handles = row_backward(handles)
0824
0825 startpage = previous_row_start(handles.positions,handles.startpage);
0826 endpage = previous_row_end(handles.positions,handles.endpage);
0827
0828 if number_of_rows(handles) < handles.number_rows
0829 handles.startpage = startpage;
0830 handles.endpage = length(handles.positions(:,1));
0831 elseif handles.startpage == 1;
0832 handles.startpage = 1;
0833 handles.endpage = handles.endpage;
0834 else
0835 handles.startpage = startpage;
0836 handles.endpage = endpage;
0837 end
0838
0839 ;
0840
0841 function handles = BrowseDirectory(handles)
0842
0843
0844
0845
0846
0847
0848
0849
0850 load('-mat', 'specicons');
0851 set_status(handles, ['Viewing all ', num2str(handles.nsegments),' segments']);
0852 handles.mapindex = [1:handles.nsegments];
0853 handles.image_list = IconList;
0854 handles = reposition_images(handles, handles.image_list);
0855 handles.cpositions = get_curr_position(handles);
0856 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
0857 handles.mode='browse';
0858
0859
0860
0861
0862
0863 function NextRowButton_Callback(hObject, eventdata, handles)
0864
0865
0866
0867 if handles.cnrows > 1
0868 handles = row_forward(handles);
0869 handles.cpositions = get_curr_position(handles);
0870 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
0871 end
0872 guidata(gcbo,handles);
0873
0874
0875 function PreviousRowButton_Callback(hObject, eventdata, handles)
0876
0877
0878
0879 if handles.cnrows > 1
0880 handles = row_backward(handles);
0881 handles.cpositions = get_curr_position(handles);
0882 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
0883 end
0884 guidata(gcbo,handles);
0885
0886
0887 function LoadDirectoryButton_Callback(hObject, eventdata, handles)
0888
0889
0890
0891
0892 directoryname = uigetdir('','Change directory');
0893
0894 if not(directoryname == 0)
0895 handles.directory = directoryname;
0896 set(handles.DirectoryEditBox, 'String',directoryname);
0897 cd(handles.directory);
0898 end
0899 guidata(gcbo,handles);
0900 ;
0901
0902 function im_index = coordinate2index(handles,xpos,ypos)
0903
0904
0905
0906
0907 if (xpos < 0) || (ypos < 0) || (ypos > handles.classified_height) || (xpos > handles.classified_width)
0908 im_index = 0;
0909 else
0910 im_index = 0;
0911 npos = length(handles.cpositions(:,1));
0912 i = 1;
0913 while (i <= npos) && (im_index < 1)
0914 if (xpos >= handles.cpositions(i,2)) && (xpos <= (handles.cpositions(i,2) + handles.images_dim(handles.startpage + (i-1), 2)))
0915 if (ypos >= handles.cpositions(i,1)) && (ypos <= (handles.cpositions(i,1) + handles.images_dim(handles.startpage + (i-1),1)))
0916 im_index = i;
0917 end
0918 end
0919 i = i+1;
0920 end
0921 end
0922 ;
0923
0924 function setnavigationbuttons(handles)
0925
0926
0927 if handles.NextIndex == handles.nsegments
0928 set(handles.NextSpectraButton,'Enable','off');
0929 elseif handles.NextIndex > 1
0930 set(handles.PreviousSpectraButton,'Enable','on');
0931 elseif handles.NextIndex == 1
0932 set(handles.PreviousSpectraButton,'Enable','off');
0933 set(handles.NextSpectraButton,'Enable','on');
0934 end
0935
0936 function DummyClassifyAxesClickCallBack(src,eventdata,handles)
0937
0938 set(handles.ClassifyButton,'Enable','on');
0939 set(handles.NewClassButton,'Visible','off');
0940 set(handles.NextSpectraButton,'Enable','on');
0941 set(handles.PreviousSpectraButton,'Enable','on');
0942 set(handles.ModePopupMenu,'Enable','on');
0943 handles.submode = 'select';
0944 setnavigationbuttons(handles);
0945 guidata(gcbo,handles);
0946
0947
0948 function ClassifyAxesClickCallBack(src,eventdata)
0949
0950 handles = guidata(gcbo);
0951
0952
0953
0954
0955 pos = get(handles.ClassifiedAxes,'CurrentPoint');
0956 cposition = coordinate2index(handles,pos(1,1),pos(1,2));
0957
0958 if strcmp(handles.mode,'browse') && (cposition > 0)
0959 handles.NextIndex = handles.mapindex((cposition - 1) + handles.startpage);
0960 handles=ConfigureClassSegment(handles);
0961 handles=ConfigureSpecPlot(eventdata,handles);
0962 else
0963
0964
0965 ;
0966 end
0967
0968
0969 if strcmp('class-view',handles.mode) && strcmp('select',handles.submode) && (cposition > 0)
0970 class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
0971 handles = configureclassmembers(handles,class.name);
0972 handles.mode = 'class-members';
0973 handles.submode = 'select';
0974 handles = SetModePopupMenu(handles,'class members');
0975 set(handles.TypifyClassButton,'Visible','on');
0976 set(handles.RemoveClassButton,'Visible','off');
0977 set_status(handles, ['Viewing ' num2str(length(handles.mapindex)),' class members']);
0978 end
0979
0980 if strcmp('class-view',handles.mode) && strcmp('select-class',handles.submode)
0981 if cposition == 0
0982 set(handles.ClassifyButton,'Enable','on');
0983 set(handles.NewClassButton,'Visible','off');
0984
0985 else
0986 class = handles.classes(handles.mapindex(cposition + (handles.startpage - 1)));
0987 handles.segments(handles.NextIndex).class = class.name;
0988 handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers = handles.classes(handles.mapindex(cposition + (handles.startpage - 1))).nmembers + 1;
0989 set(handles.ClassifyButton,'String','Declassify');
0990 handles = SetModePopupMenu(handles,'class members');
0991 handles = configureclassmembers(handles,class.name);
0992 handles.mode = 'class-members';
0993 handles.submode = 'xxx';
0994 set_status(handles,'');
0995 end
0996 set(handles.ClassifyButton,'Enable','on');
0997 set(handles.NewClassButton,'Visible','off');
0998 set(handles.NextSpectraButton,'Enable','on');
0999 set(handles.PreviousSpectraButton,'Enable','on');
1000 set(handles.ModePopupMenu,'Enable','on');
1001 handles.submode = 'select';
1002 end
1003
1004 if strcmp(handles.mode,'class-members') && strcmp(handles.submode,'typify')
1005 if cposition == 0
1006 set(handles.TypifyClassButton, 'Enable','on');
1007 else
1008 sindex = handles.mapindex(cposition + (handles.startpage - 1));
1009 cindex = returnclassindex(handles,handles.segments(sindex).class);
1010 handles.classes(cindex).specfilename = handles.segments(sindex).specfilename;
1011 handles.classes(cindex).length = handles.segments(sindex).end - handles.segments(sindex).start;
1012 load('-mat','specicons');
1013 handles.classes(cindex).iconS = IconList{sindex};
1014 handles.subclass = 'xxx';
1015 set(handles.TypifyClassButton, 'Enable','on');
1016 set_status(handles,'');
1017 end
1018 end
1019
1020 if strcmp(handles.mode,'class-view') && strcmp(handles.submode,'remove-class')
1021 if cposition == 0
1022 set(handles.RemoveClassButton, 'Enable','on');
1023 else
1024
1025
1026 cindex = handles.mapindex(cposition + (handles.startpage - 1));
1027 classname = handles.classes(cindex).name;
1028
1029 for i = 1:handles.nsegments
1030 if strcmp(classname,handles.segments(i).class)
1031 handles.segments(i).class = '';
1032 end
1033 end
1034
1035 if handles.nclasses > 1
1036 handles.classes = [handles.classes(1:(cindex-1)) handles.classes((cindex+1):handles.nclasses)];
1037 handles.nclasses = handles.nclasses - 1;
1038 handles = configureclassview(handles,'select-class');
1039 else
1040 handles.classes = [];
1041 handles.nclasess = 0;
1042 handles.image_list = {};
1043 axes(handles.ClassifiedAxes);
1044 image(uint8(zeros(handles.classified_height,handles.classified_width)));
1045 end
1046
1047 if strcmp(handles.segments(handles.NextIndex).class,'')
1048 set(handles.ClassifyButton,'String','Classify');
1049 end
1050
1051 set(handles.RemoveClassButton, 'Visible', 'off');
1052 set(handles.RemoveClassButton, 'Enable','on');
1053
1054 end
1055 set_status(handles,'');
1056 end
1057 setnavigationbuttons(handles);
1058
1059
1060 guidata(gcf,handles);
1061
1062
1063
1064
1065
1066 function handles = configureclassview(handles,submode)
1067
1068 handles.mode = 'class-view';
1069 handles.submode = submode;
1070 set_status(handles, ['Select a class']);
1071 handles.mapindex = [1 : handles.nclasses];
1072 handles.mapindex = sortindexbypop(handles);
1073
1074 handles = cindex2imagelist(handles);
1075
1076
1077
1078
1079 handles = reposition_images(handles, handles.image_list);
1080 handles.cpositions = get_curr_position(handles);
1081 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1082
1083 ;
1084
1085 function handles = SetModePopupMenu(handles,viewstring)
1086 popmodes = get(handles.ModePopupMenu,'String');
1087
1088 find_index = 0;
1089 i = 1;
1090 while (i <= length(popmodes)) && not(strcmp(popmodes(i),viewstring))
1091 i = i + 1;
1092 end
1093
1094 if i <= length(popmodes)
1095 set(handles.ModePopupMenu,'Value',[i]);
1096 end
1097
1098
1099 function ModePopupMenu_Callback(hObject, eventdata, handles)
1100
1101
1102
1103
1104
1105
1106
1107
1108 nmode = get(hObject,'Value');
1109 modeview = get(hObject,'String');
1110
1111 if strcmp(modeview(nmode),'all')
1112 handles.mode = 'browse';
1113 handles.submode = 'select';
1114 handles=BrowseDirectory(handles);
1115 set(handles.RemoveClassButton,'Visible','off');
1116 set(handles.TypifyClassButton, 'Visible', 'off');
1117
1118 elseif strcmp(modeview(nmode),'class view')
1119 if handles.nclasses >= 1
1120 handles = configureclassview(handles,'select');
1121 handles.mode = 'class-view';
1122 handles.submode = 'select';
1123 set(handles.RemoveClassButton,'Visible','on');
1124 set(handles.RemoveClassButton,'Enable','on');
1125 set(handles.TypifyClassButton, 'Visible', 'off');
1126 set_status(handles,['Viewing all ' num2str(handles.nclasses) ' classes'])
1127 else
1128 axes(handles.ClassifiedAxes);
1129 handles.hiclass = image(uint8(zeros(handles.classified_height,handles.classified_width)));
1130 handles.mode = 'class-view';
1131 handles.submode = 'xxx';
1132 set_status(handles,'');
1133 end
1134 elseif strcmp(modeview(nmode),'unclassified') || (strcmp(handles.segments(handles.NextIndex).class,'') && strcmp(modeview(nmode),'class members'))
1135 handles = configureclassmembers(handles,'');
1136 set_status(handles,['A total of ' num2str(length(handles.mapindex)) ' unclassified segments ']);
1137 handles = SetModePopupMenu(handles,'unclassified');
1138 handles.mode = 'browse';
1139 handles.submode = 'select';
1140 set(handles.RemoveClassButton, 'Visible', 'off');
1141 elseif strcmp(modeview(nmode),'class members')
1142 handles = configureclassmembers(handles,handles.segments(handles.NextIndex).class);
1143 set_status(handles,['Viewing ' num2str(length(handles.mapindex)) ' class members']);
1144 handles.mode = 'class-members';
1145 handles.submode = 'select';
1146 set(handles.TypifyClassButton,'Visible', 'on');
1147 set(handles.RemoveClassButton, 'Visible', 'off');
1148 end
1149
1150 guidata(gcbo,handles);
1151
1152
1153 function ModePopupMenu_CreateFcn(hObject, eventdata, handles)
1154
1155
1156
1157
1158
1159
1160 if ispc
1161 set(hObject,'BackgroundColor','white');
1162 else
1163 set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
1164 end
1165
1166 function set_status(handles, statusstring)
1167 set(handles.SegInfoText,'String',statusstring);
1168 set(handles.SegInfoText,'Visible','on');
1169 ;
1170
1171
1172
1173
1174
1175 function handles = configureclassmembers(handles,classname)
1176
1177 handles.mapindex = select_class(handles,handles.segments,classname);
1178
1179 if length(handles.mapindex) > 0
1180 handles.image_list = {};
1181 load('-mat','specicons');
1182
1183 for i = 1:length(handles.mapindex)
1184 handles.image_list(i) = IconList(handles.mapindex(i));
1185 end
1186 handles = reposition_images(handles, handles.image_list);
1187 handles.cpositions = get_curr_position(handles);
1188
1189
1190 handles = plot_classified_axes(handles, handles.image_list(handles.startpage:handles.endpage), handles.cpositions);
1191
1192 else
1193 axes(handles.ClassifiedAxes);
1194 handles.hiclass = image(uint8(zeros(handles.classified_height,handles.classified_width)));
1195
1196
1197 set_status(handles,'');
1198 end
1199 ;
1200
1201 function indexfilter = select_class(handles,segments,classname)
1202
1203
1204 indexfilter = [];
1205 nclassmembers = 0;
1206 for i = 1:handles.nsegments
1207 if strcmp(segments(i).class,classname)
1208 nclassmembers = nclassmembers + 1;
1209 indexfilter(nclassmembers) = i;
1210 end
1211 end
1212
1213 function value = mapind(index)
1214
1215 value = handles.mapindex(index);
1216
1217
1218 function write_syllable_database(handles)
1219 filename = [handles.baseclassname '.dat'];
1220 fid = fopen(filename,'w+');
1221
1222 classes = handles.classes;
1223
1224 if fid > -1
1225 for i = 1:handles.nsegments
1226 segment = handles.segments(i);
1227 wavfile = segment.wavfile;
1228 specfilename = segment.specfilename;
1229 seg = [ num2str(segment.start) '\t' num2str(segment.end)];
1230 classname = [ segment.class ];
1231 typify = '';
1232 nclasses = length(classes);
1233 j = 1;
1234 while (nclasses > 0) && (j <= nclasses) && not(strcmp(segment.specfilename,classes(j).specfilename))
1235 j = j + 1;
1236 end
1237 if j <= length(classes)
1238 classes = [classes(1:j-1) classes(j+1:nclasses)];
1239 typify = '*';
1240 end
1241 fprintf(fid,[specfilename '\t' wavfile '\t' seg '\t' classname '\t' typify '\n']);
1242 end
1243 fclose(fid);
1244 end
1245 ;
1246
1247 function data = read_syllable_database(handles)
1248 filename = [handles.baseclassname '.dat'];
1249 fid = fopen(filename,'r');
1250 data = textscan(fid,'%s %s %n %n %s %s', 'delimiter','\t');
1251 data = [data(1), data(5), data(6)];
1252 fclose(fid);
1253 ;
1254
1255 function handles = merge_syllable_database(handles,data)
1256
1257
1258 load('-mat','specicons');
1259 specfilenames = data{1};
1260 classnames = data{2};
1261 typifies = data{3};
1262 ndata = length(specfilenames);
1263
1264 handles.classes = [];
1265 handles.nclasses = 0;
1266 for i = 1:ndata
1267 j=1;
1268 while (j < handles.nsegments) && not(strcmp(specfilenames(i),handles.segments(j).specfilename))
1269 j = j + 1;
1270 end
1271 if j <= handles.nsegments
1272 handles.segments(j).class = classnames{i};
1273 if strcmp(typifies(i),'*')
1274
1275 class.specfilename = specfilenames{i};
1276 class.name = classnames{i};
1277 class.length = handles.segments(j).end - handles.segments(j).start;
1278 class.iconS = IconList{j};
1279 class.nmembers = 0;
1280 handles.nclasses = handles.nclasses + 1;
1281 handles.classes = [handles.classes class];
1282 end
1283 end
1284 end
1285
1286
1287 for i = 1:handles.nclasses
1288 for j = 1 : handles.nsegments
1289 if strcmp(handles.classes(i).name,handles.segments(j).class)
1290 handles.classes(i).nmembers = handles.classes(i).nmembers + 1;
1291 end
1292 end
1293 end
1294
1295
1296
1297 function SaveButton_Callback(hObject, eventdata, handles)
1298
1299
1300
1301
1302 write_syllable_database(handles);
1303
1304
1305
1306
1307 function QuickModeButton_Callback(hObject, eventdata, handles)
1308
1309
1310
1311
1312
1313
1314 function SkipButton_Callback(hObject, eventdata, handles)
1315
1316
1317
1318
1319