Code covered by the BSD License  

Highlights from
Autocorrelation Pitch Detector

image thumbnail

Autocorrelation Pitch Detector

by

 

30 Jan 2014 (Updated )

Implements a pitch period detection algorithm using modified autocorrelation method

Callbacks_ac_pitch_GUI25(f,C,start_path)
function Callbacks_ac_pitch_GUI25(f,C,start_path)
%SENSE COMPUTER AND SET FILE DELIMITER
switch(computer)				
    case 'MACI64',		char= '/';
    case 'GLNX86',  char='/';
    case 'PCWIN',	char= '\';
    case 'PCWIN64', char='\';
    case 'GLNXA64', char='/';
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x=C{1,1};
y=C{1,2};
a=C{1,3};
b=C{1,4};
u=C{1,5};
v=C{1,6};
m=C{1,7};
n=C{1,8};
lengthbutton=C{1,9};
widthbutton=C{1,10};
enterType=C{1,11};
enterString=C{1,12};
enterLabel=C{1,13};
noPanels=C{1,14};
noGraphicPanels=C{1,15};
noButtons=C{1,16};
labelDist=C{1,17};%distance that the label is below the button
noTitles=C{1,18};
buttonTextSize=C{1,19};
labelTextSize=C{1,20};
textboxFont=C{1,21};
textboxString=C{1,22};
textboxWeight=C{1,23};
textboxAngle=C{1,24};
labelHeight=C{1,25};
fileName=C{1,26};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%PANELS
for j=0:noPanels-1
uipanel('Parent',f,...
'Units','Normalized',...
'Position',[x(1+4*j) y(1+4*j) x(2+4*j)-x(1+4*j) y(3+4*j)-y(2+4*j)]);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%GRAPHIC PANELS
for i=0:noGraphicPanels-1
switch (i+1)
case 1
graphicPanel1 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 2
graphicPanel2 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 3
graphicPanel3 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 4
graphicPanel4 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%TITLE BOXES
for k=0:noTitles-1
switch (k+1)
case 1
titleBox1 = uicontrol('parent',f,...
'Units','Normalized',...
'Position',[u(1+4*k) v(1+4*k) u(2+4*k)-u(1+4*k) v(3+4*k)-v(2+4*k)],...
'Style','text',...
'FontSize',textboxFont{k+1},...
'String',textboxString(k+1),...
'FontWeight',textboxWeight{k+1},...
'FontAngle',textboxAngle{k+1});
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%BUTTONS
for i=0:(noButtons-1)
enterColor='w';
if strcmp(enterType{i+1},'pushbutton')==1 ||strcmp(enterType{i+1},'text')==1
enterColor='default';
end
if (strcmp(enterLabel{1,(i+1)},'')==0 &&...
        strcmp(enterLabel{1,(i+1)},'...')==0) %i.e. there is a label
%creating a label for some buttons
uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i)-labelDist-labelHeight(i+1) ...
(m(2+2*i)-m(1+2*i)) labelHeight(i+1)],...
'Style','text',...
'String',enterLabel{i+1},...
'FontSize', labelTextSize(i+1),...
'HorizontalAlignment','center');
end
switch (i+1)
case 1
button1=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button1Callback);
case 2
button2=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button2Callback);
case 3
button3=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button3Callback);
case 4
button4=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button4Callback);
case 5
button5=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button5Callback);
case 6
button6=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button6Callback);
case 7
button7=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button7Callback);
case 8
button8=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button8Callback);
case 9
button9=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button9Callback);
case 10
button10=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button10Callback);
case 11
button11=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button11Callback);
case 12
button12=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button12Callback);
case 13
button13=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button13Callback);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%USER CODE FOR THE VARIABLES AND CALLBACKS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize Variables
    curr_file=1;
    fs=8000;
    fsd=20000;
    directory_name='abcd';
    wav_file_names='abce';
    fin_path='filename';
    fname='output';
    nsamp=1;
    Lm=40;
    L=400;
    Rm=10;
    R=100;
    imf=1;
    xin=[];
    y=[];
    alpha=60;
    LM=5;
    conf_thr=0.33;

% Name the GUI
    set(f,'Name','ac_pitch_detector');

% CALLBACKS
% Callback for button1 -- Get Speech Files Directory
 function button1Callback(h,eventdata)
     directory_name=uigetdir(start_path,'dialog_title');
     A=strvcat(strcat((directory_name),[char,'*.wav']));
     struct_filenames=dir(A);
     wav_file_names={struct_filenames.name};
     set(button2,'String',wav_file_names);
     
% once the popupmenu/drop down menu is created, by default, the first
% selection from the popupmenu/drop down menu id not called
    indexOfDrpDwnMenu=1;
    
% by default first option from the popupmenu/dropdown menu will be loaded
    [curr_file,fs]=loadSelection(directory_name,wav_file_names,indexOfDrpDwnMenu);
 end

% Callback for button2 -- Choose speech file for play and plot
 function button2Callback(h,eventdata)
     indexOfDrpDwnMenu=get(button2,'val');
     [curr_file,fs]=loadSelection(directory_name,wav_file_names,indexOfDrpDwnMenu);
 end

%*************************************************************************
% function -- load selection from designated directory and file
%
function [curr_file,fs]=loadSelection(directory_name,wav_file_names,...
    indexOfDrpDwnMenu);
%
% read in speech/audio file
% fin_path is the complete path of the .wav file that is selected
    fin_path=strcat(directory_name,char,strvcat(wav_file_names(indexOfDrpDwnMenu)));
    
% clear speech/audio file
    clear curr_file;
    
% read in speech/audio signal into curr_file; sampling rate is fs 
    [curr_file,fs]=wavread(fin_path);
    xin=curr_file*32768;
    
% Button12Callback
    set(button12,'string',num2str(fs));
       
% create title information with file, sampling rate, number of samples
    fname=wav_file_names(indexOfDrpDwnMenu);
    FS=num2str(fs);
    nsamp=num2str(length(curr_file));
    file_info_string=strcat('  file: ',fname,', fs: ',FS,' Hz, nsamp:',nsamp);
    
% read in filename (fname) from cell array
    fname=wav_file_names{indexOfDrpDwnMenu};
end

% Callback for button11 -- play speech file
 function button11Callback(h,eventdata)
     soundsc(curr_file,fs);
 end

% Callback for button 12 -- original sampling rate
 function button12Callback(h,eventdata)
        set(button12,'string',num2str(fs));
 end

% Callback for button3 -- imf: male(1)/female(2) pitch period range switch
 function button3Callback(h,eventdata)
     imf=get(button3,'val');
 end

% Callback for button4 -- fsd: sampling rate for speech processing
 function button4Callback(h,eventdata)
    % fsd=str2num(get(button4,'string'));
     Index=get(button4,'val');
     a = [6000 8000 10000 16000 20000];
     fsd = a(Index); 
 end

% Callback for button5 -- Lm: analysis frame length in msec
 function button5Callback(h,eventdata)
     Lm=str2num(get(button5,'string'));
      if (Lm < 1 || Lm > 100)
         waitfor(errordlg('The frame length must be between 1 and 100'));
         return;
     end
 end

% Callback for button6 -- Rm: analysis frame shift in msec
 function button6Callback(h,eventdata)
     Rm=str2num(get(button6,'string'));
      if (Rm < 1 || Rm > 100)
         waitfor(errordlg('The frame duration must be between 1 and 100'));
         return;
     end
 end

% Callback for button7 -- alpha: center clipping level (%))
 function button7Callback(h,eventdata)
     alpha=str2num(get(button7,'string'));
     if (alpha < 0 || alpha > 100)
         waitfor(errordlg('The center clipping percentage level must be between 0 and 100'));
         return;
     end
 end

% Callback for button8 -- LM: median size in samples
 function button8Callback(h,eventdata)
     LM=str2num(get(button8,'string'));
     if (LM < 3 || LM > 11)
         waitfor(errordlg('The median size must be between 3 and 11'));
         return;
     end
 end

% Callback for button13 -- conf_thr; confidence threshold
 function button13Callback(h,eventdata)
     conf_thr=str2num(get(button13,'string'));
      if (conf_thr < 0.1 || conf_thr > 0.9)
         waitfor(errordlg('The confidence threshold must be between 0.1 and 0.9'));
         return;
     end
 end

% Callback for button9 -- run autocorrelation pitch detector
 function button9Callback(h,eventdata)
     
% check editable buttons for changes
    button3Callback(h,eventdata);
    button4Callback(h,eventdata);
    button5Callback(h,eventdata);
    button6Callback(h,eventdata);
    button7Callback(h,eventdata);
    button8Callback(h,eventdata);
    
% call autocorrelation pitch detector
    ac_pitch_detector(xin,fs,alpha,imf,fsd,Lm,Rm,LM,fname);
 end

%**********************************************************************
function ac_pitch_detector(xin,fs,alpha,imf,fsd,Lm,Rm,LM,fname)
%
% Simple autocorrelation-based pitch detector
%   - use modified cross-correlation with center clipping
%       - read in alpha parameter for center clipping level
%   - read in parameters of autocorrelation and smoother
%       - fsd = standard sampling rate for data (must convert sampling rate
%       if not the standard
%       - Lm = nominal frame length (msec) for autocorrelation; must convert
%       to samples at standard sampling rate
%       - Rm = nominal frame shift (msec) for autocorrelation; must convert
%       to samples at standard sampling rate
%       - imf = 1 for male, 2 for female talker; used to set range of valid
%       pitch periods
%       - LM = size of median smoother in samples at sampling rate fsd; 
%       typically a value of LM=5 is used
%       - speech filename = s5 (example)
%
%   - read in speech samples from specified speech filename
%   - convert to sampling rate of fsd (if sampling rate is not fsd)
%   - highpass filter to eliminate DC, hum; stopband from 0 to 80 Hz, 
%   passband from 150 to Fs/2 Hz;
%   - convert Lm and Rm from msec to samples as follows; L=Lm*fsd/1000; 
%   R=Rm*fsd/1000
%   - block speech into frames of length L samples with frame shift of 
%   R samples, starting at sample n=0 (i.e., first frame goes from 
%   n=0 to n=L-1); modified first frame goes from n=0 to n+L+ppdhigh-1, 
%   where ppdhigh is the maximum correlation index (ppdhigh set to fsd/60 
%   for male speakers and fsd/150 for female speakers
%   - compute the desired correlation for current frame
%   - search modified correlation from ppdlow to ppdhigh for maximum value,
%   and use the correlation value at the maximum (relative to the
%   correlation value at 0 lag), as the confidence score; ppdlow is set
%   to fsd/200 for male speakers and to fsd/300 for female speakers
%   - set a threshold on the confidence scores as:
%   thr=0.35*confidence; set pitch period to zero when confidence
%   score falls below confidence score threshold
%   - plot raw pitch period locations and confidence scores
%   - use an LM point median smoother and smooth pitch period scores and
%   confidence scores
%   - plot median smoothed pitch period scores along with median smoothed
%   confidence scores
%   - save analysis files in out_autocorrelation.mat 

    clear pp confidence pps confidences confidencel confidencemax;
    clear confidencethr pm cm;
      
% resample if fs ~= fsd
    y=xin;
    if (fs ~= fsd)
        y=srconv(xin,fs,fsd);
    end
    ly=length(y);
    
% convert Lm, Rm to samples
    L=round(Lm*fsd/1000);
    R=round(Rm*fsd/1000);
    
% design highpass filter for eliminating DC, hum
    n=300;
    fl1=80;
    fh1=150;
    bhp=hpf(n,fl1,fh1,fsd,0);
    n=n+1;
    
% highpass filter the speech file and compensate for the linear phase delay
    ye=[y; zeros(1,n)'];
    yf=filter(bhp,1,ye);
    yf=yf((n-1)/2+1:ly+(n-1)/2);
    
% compute frame correlation and confidence score
% scale alpha by 100 to get percentage
    alphar=alpha/100;
    [pp,confidence]=pitch_detect_ac(yf,fsd,imf,alphar,L,R,LM);
    n=1:length(pp);
    pps=pp;
    confidences=confidence;
    
% process confidence scores to set to 0 any low confidence frame
    confidence(find(confidence < 0))=0.0001;
    confidencel=log10(confidence+0.0001);
    confidencemax=max(confidence);
    confidencethr=confidencemax*conf_thr;  % 0.33;
    pp(find(confidence < confidencethr))=0;

    
% compute median pitch period and median log confidence scores
%
    pm=medf(pp,LM,length(pp));
    cm=medf(confidence,LM,length(confidence));
    
% clear graphics Panel 4
    reset(graphicPanel4);
    axes(graphicPanel4);
    cla;
    
% plot speech waveform in graphics Panel 4; first normalize to range [-1  +1];
        yfm=max(abs(yf));
        yn=yf/yfm;
        nfrm=length(pp);
        ss1=L/2+1-R;
        es1=L/2+1+nfrm*R;
        stringx=['Time in Seconds;  fsd:',num2str(fsd),' samples/second'];
        xscale=(ss1:es1)/fsd;
        plot(xscale,yn(ss1:es1),'b');xlabel(stringx);
        ylabel('Amplitude');grid on; axis([ss1/fsd,es1/fsd,min(yn),max(yn)]);
        
% clear graphics Panel 3
    reset(graphicPanel3);
    axes(graphicPanel3);
    cla;
    
% plot raw pitch period contour in graphics Panel 3
        plot(n,pp,'k','LineWidth',2);
        xlabel('Frame Number'),ylabel('Pitch Period');
        axis ([0,length(pp)+1,0,max(pp)*1.35]);
        grid on;legend('raw pitch period contour');
        stitle=sprintf(' file: %s, fsd: %d, alpha: %d, Lm: %d, Rm: %d, median, LM: %d',...
            fname,fsd,alpha,Lm,Rm,LM);
    
% clear graphics Panel 2
    reset(graphicPanel2);
    axes(graphicPanel2);
    cla;
    
% plot median-smoothed pitch period contour in graphics Panel 2
        plot(n,pm,'k','LineWidth',2); grid on;
        axis ([0,length(pp)+1,0,max(pm)*1.35]);
        xlabel('Frame Number'),ylabel('Pitch Period');
        legend('median smoothed pitch period contour');
        
% clear graphics Panel 1
    reset(graphicPanel1);
    axes(graphicPanel1);
    cla;
    
% plot median-smoothed confidence score in graphics Panel 1
        plot(n,cm,'k','LineWidth',2),...
        xlabel('Frame Number'),ylabel('Normalized Confidence Score');
        axis ([0,length(pp)+1,0,max(cm)*1.35]); grid on;
        legend('confidence score');
    
% save pitch period contours (appropriately scaled back to the original
% sampling rate) in mat files out_autocorrelation_pitch_period.mat 
        ppmi=round(pm'*fs/fsd);
        fsave=strcat('out_AC_',fname(1:length(fname)-4),'.mat');
        save (fsave, 'ppmi') ;
        
% display fname and signal processing parameters in titleBox1
    stitle1=strcat('Autocorrelation Pitch Detector -- ',stitle);
    set(titleBox1,'string',stitle1);
    set(titleBox1,'FontSize',15);
end

%*******************************************************************
function [pd1,p1]=pitch_detect_ac(peaksigo,fsd,imf,alpha,L,R,LM)
%
% function to perform signal processing for autocorrelation analysis of
% speech and to estimate most likely pitch period for all voiced frames
%
% Outputs:
%   pd1=pitch period contour for given signal
%   p1=confidence score (normalized to [0 1] scale
%
% Inputs:
%   peaksigo=input speech signal
%   fsd=sampling rate for signal processing
%   imf=male/female pitch range option 
%       (1 for male talkers, 2 for female talkers)
%   alpha=center clipping level percentage (0-100)
%   L=analysis frame duration in samples
%   R=analysis frame shift in samples
%   LM=size of median smoother in samples
%
% low pitch period corresponds to 300 Hz pitch
% high pitch period corresponds to 50 Hz pitch
    clear pd1 p1;
    
% set high and low periods for male and female speakers
    if (imf == 1) % male speaker
        ppdlow=round(fsd/200);
        ppdhigh=round(fsd/75);
    elseif (imf == 2) % female speaker
        ppdlow=round(fsd/300);
        ppdhigh=round(fsd/150);
    end
    
% utilize L sample frames; shift by R samples
    ls=length(peaksigo);
    fcenter=L/2;
    p1=[];
    pd1=[];
    while (fcenter+L/2 <= ls)
        frame1a=peaksigo(max(fcenter-L/2,1):fcenter+L/2);
        frame1b=peaksigo(fcenter+L/2+1:min(fcenter+L/2+ppdhigh,ls));
        frame2=[frame1a' frame1b'];
        
% center clipping at alpha*amax
        amax=max(frame2);
        xclip=amax*alpha;
        frame1a(find(abs(frame1a) < xclip))=0;
        frame2(find(abs(frame2) < xclip))=0;
        
% compute modified autocorrelation of frame1a and frame2
        lf=max(length(frame1a),length(frame2));
        c=xcorr(frame1a,frame2);
        cmax=max(c);
        pmax=max(c(lf+ppdlow:lf+ppdhigh));
        if (cmax > 0)
            pc=pmax/cmax;
            ploc=find(c(lf+ppdlow:lf+ppdhigh) == pmax);
            p1=[p1 pc];
            pd1=[pd1 ploc(1)+ppdlow-1];
        else
            pmax=0;
            p1=[p1 0];
            pd1=[pd1 0];
        end
        fcenter=fcenter+R;
    end 
end

% Callback for button10 -- close GUI
 function button10Callback(h,eventdata)
     close(gcf);
 end
end

Contact us