function sigdemo1(action,in1,in2);
%SIGDEMO1 Interactive signal demo - 1 : DFT of a signal
%	Demonstrates MATLAB's graphic user interface using Handle Graphics
%       while illustrating some basic signal processing concepts, such as 
%	sampling, aliasing, and windowing.

%	Author: T. Krauss
% 	11/3/92, updated 2/9/93
%	(c) Copyright 1984-93, by The MathWorks, Inc.

%	possible actions:
%	  'start'
%	  'down'
%	  'move'
%	  'up'
%	  'redraw'
%	  'done'
%	  'setwindow'
%	  'showwind'

if nargin<1,
    action='start';
end;

global SIGDEMO1_DAT

if strcmp(action,'start'),
% graphics initialization
    clf reset;
    set(gcf,'Units','normalized','backingstore','off');

    popup=uicontrol('Style','Popup','String','cosine|square|sawtooth',...
        'Position',[.03 .02 .2 .08],'Units','normalized',...
        'CallBack','sigdemo1(''redraw'')');

    if exist('freqz')==2,
        wind_menu=uimenu('Label','Window');
        w1=uimenu(wind_menu,'Label','rectangular','Callback',...
                  'sigdemo1(''setwindow'',1)');
        w2=uimenu(wind_menu,'Label','triangular','Callback',...
                  'sigdemo1(''setwindow'',2)');
        w3=uimenu(wind_menu,'Label','hanning','Callback',...
                  'sigdemo1(''setwindow'',3)');
        w4=uimenu(wind_menu,'Label','hamming','Callback',...
                  'sigdemo1(''setwindow'',4)');
        w5=uimenu(wind_menu,'Label','chebyshev');
        w5_20=uimenu(w5,'Label','20 dB atten.','Callback',...
                  'sigdemo1(''setwindow'',5,20)');
        w5_30=uimenu(w5,'Label','30 dB atten.','Callback',...
                  'sigdemo1(''setwindow'',5,30)');
        w5_40=uimenu(w5,'Label','40 dB atten.','Callback',...
                  'sigdemo1(''setwindow'',5,40)');
        w6=uimenu(wind_menu,'Label','kaiser');
        w6_1=uimenu(w6,'Label','parameter = 1','callback',...
                  'sigdemo1(''setwindow'',6,1)');
        w6_15=uimenu(w6,'Label','parameter = 4','callback',...
                  'sigdemo1(''setwindow'',6,4)');
        w6_2=uimenu(w6,'Label','parameter = 9','callback',...
                  'sigdemo1(''setwindow'',6,9)');
        w7=uimenu(wind_menu,'Label','Show window...',...
                     'Callback','sigdemo1(''showwind'');');
    end;  % if statement

    freq_text=uicontrol('Style','text','Position',[.33 .02 .28 .08],...
        'Units','normalized','BackgroundColor','black',...
        'ForegroundColor','white','String','Fundamental (Hertz):',...
        'HorizontalAlignment','right');

    freq_field=uicontrol('Style','edit','Position',[.63 .02 .12 .08],...
        'Units','normalized','String','5',...
        'CallBack','sigdemo1(''setfreq''); sigdemo1(''redraw'')');

    done_button=uicontrol('Style','Pushbutton','Position',[.85 .02 ...
        .12 .08],'Units','normalized','Callback',...
        'sigdemo1(''done'')','String','Done');

    help sig1help    % show help in command window

    % Create intial signal
    N=201;     % number of samples
%    N=21;
    amp=0.5;
    freq=5;    % hertz
    t0=0;      % seconds
    t1=1;      % seconds
    t=linspace(t0,t1,N)';
    T=(t1-t0)/N;            % sampling rate in seconds
    M=256;     % length of fft
    window=ones(N,1);    % use window to lower side-lobes in the freq. domain
                             % (makes peaks wider)

    min_dB = -40; % freq. domain lower axis limit

    % create axes for time domain and frequency domain plot
    ax_freq=axes('Position',[.15 .2 .8 .3],'XLim',...
             [0 1/(2*T)],'YLim',[min_dB 50]);
    
    % time domain
    val = get(popup,'Value');
    if (val == 1),
        f=amp*cos(freq*t*2*pi);
    elseif (val == 2),   % square wave
        tt=freq*t*2*pi;
        tmp=rem(tt,2*pi);
        f=amp*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
    elseif (val == 3),   % sawtooth
        tt=freq*t*2*pi;
        f=amp*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
    end;

    % frequency domain
    F=fft(window.*f,2*M);
    F=F(1:M);
    w=(0:M-1)*pi/M;
    FF=20*log10(abs(F));
    ind=find(FF<min_dB);
    FF(ind)=NaN*ones(size(ind)); % put NaN's in where
         % min_dB shows up - this is to work around no clipping in xor mode
    freq_line=plot(w/2/pi/T,FF,'EraseMode','xor');
    axis([0 1/(2*T)  min_dB 50]);
    grid;
    ylabel('Magnitude (dB)');
    xlabel('Frequency (Hertz)');

    ax_time=axes('Position',[.15 .62 .8 .3],'XLim',[t0 t1],'YLim',[-1 1]);
    time_line=plot(t,f,'EraseMode','xor');
    axis([t0 t1 -1 1]);
    % (set to xor mode to prevent re-rendering, that is, for speed)
    grid;
    ylabel('Waveform');
    xlabel('Time (Seconds)');
    title('Click and drag waveform to change fundamental and amplitude');

    set(time_line,'ButtonDownFcn','sigdemo1(''down'')');
    SIGDEMO1_DAT = [freq; amp; N; M; min_dB; 0; 0; ...
         time_line; freq_line; freq_field; popup; -1; gcf; t(:); window(:)];

elseif strcmp(action,'down'),
    % assumes that a line was clicked 
    time_line=SIGDEMO1_DAT(8);    
    axes(get(time_line,'parent'));     % set the right axes

    % Obtain coordinates of mouse click location in axes units
    pt=get(gca,'currentpoint');
    x=pt(1,1);
    y=pt(1,2);


% find closest vertex of line to mouse click location (call it fixed_x, fixed_y)

    line_x=get(time_line,'XData');
    line_y=get(time_line,'YData');
    set(gca,'units','pixels');     % distance must bein pixels
    p=get(gca,'pos');
    xa=get(gca,'xlim');
    ya=get(gca,'ylim');
    
    dist=((line_x-x)*p(3)/(xa(2)-xa(1))).^2 + ...
         ((line_y-y)*p(4)/(ya(2)-ya(1))).^2;
    [temp,i]=min(dist);
    fixed_x=line_x(i);
    fixed_y=line_y(i);
    set(time_line,'LineStyle','--');

    SIGDEMO1_DAT(6)=fixed_x;
    SIGDEMO1_DAT(7)=fixed_y;

    set(gcf,'WindowButtonMotionFcn', 'sigdemo1(''move'')');
    set(gcf,'WindowButtonUpFcn', 'sigdemo1(''up'')');
    % set(gcf,'userdata',u);

elseif strcmp(action,'move'),
    % u = get(gcf,'userdata');
    freq=SIGDEMO1_DAT(1);
    amp=SIGDEMO1_DAT(2);
    N=SIGDEMO1_DAT(3);
    M=SIGDEMO1_DAT(4);
    min_dB=SIGDEMO1_DAT(5);
    fixed_x=SIGDEMO1_DAT(6);
    fixed_y=SIGDEMO1_DAT(7);
    time_line=SIGDEMO1_DAT(8);
    freq_line=SIGDEMO1_DAT(9);
    freq_field=SIGDEMO1_DAT(10);
    popup=SIGDEMO1_DAT(11);
    t=SIGDEMO1_DAT(14:14+N-1);
    window=SIGDEMO1_DAT(14+N:14+N+N-1);

    pt=get(gca,'currentpoint');
    x=pt(1,1);
    y=pt(1,2);

    amp1=y/fixed_y*amp;
    if (abs(amp1)>1.0),
       amp1=1.0*sign(amp1);
    end;
    if (abs(amp1)<0.05),
       amp1=0.05*sign(amp1);
    end;
    freq1=fixed_x/x*freq;

    val = get(popup,'Value');
    if (val == 1),
        f=amp1*cos(freq1*t*2*pi);
    elseif (val == 2),   % square wave
        tt=freq1*t*2*pi;
        tmp=rem(tt,2*pi);
        f=amp1*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
    elseif (val == 3),   % sawtooth
        tt=freq1*t*2*pi;
        f=amp1*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
    end;
    set(time_line,'YData',f);
    F=fft(window.*f,2*M);
    F=F(1:M);
    w=(0:M-1)*pi/M;
    FF=20*log10(abs(F));
    ind=find(FF<min_dB);
    FF(ind)=NaN*ones(size(ind)); % put NaN's in where
             % min_dB shows up - this is to work around no clipping in xor mode
    set(freq_line,'YData',FF);
    set(freq_field,'String',num2str(freq1));

elseif strcmp(action,'up'),
    pt=get(gca,'currentpoint');
    x=pt(1,1);
    y=pt(1,2);

    set(gcf,'WindowButtonMotionFcn','');
    set(gcf,'WindowButtonUpFcn','');

    % u=get(gcf,'userdata');
    freq=SIGDEMO1_DAT(1);
    amp=SIGDEMO1_DAT(2);
    fixed_x=SIGDEMO1_DAT(6);
    fixed_y=SIGDEMO1_DAT(7);

    amp1=y/fixed_y*amp;
    if (abs(amp1)>1.0),
       amp1=1.0*sign(amp1);
    end;
    if (abs(amp1)<0.05),
       amp1=0.05*sign(amp1);
    end;
    freq1=fixed_x/x*freq;

    set(SIGDEMO1_DAT(8),'linestyle','-');
    SIGDEMO1_DAT(1)=freq1;  % set amplitude and frequency
    SIGDEMO1_DAT(2)=amp1;
    % set(gcf,'userdata',u);
    sigdemo1('redraw');

elseif strcmp(action,'done'),
    % close the figure window that is showing the window fnction:
    % u = get(gcf,'userdata');
    if (SIGDEMO1_DAT(12)~=-1),
        close(SIGDEMO1_DAT(12));
    end;
    clf reset;
    clear global SIGDEMO1_DAT

elseif strcmp(action,'redraw'),
    % recomputes time and frequency waveforms and updates display
    % u = get(gcf,'userdata');
    freq=SIGDEMO1_DAT(1);
    amp=SIGDEMO1_DAT(2);
    N=SIGDEMO1_DAT(3);
    M=SIGDEMO1_DAT(4);
    min_dB=SIGDEMO1_DAT(5);
    time_line=SIGDEMO1_DAT(8);
    freq_line=SIGDEMO1_DAT(9);
    freq_field=SIGDEMO1_DAT(10);
    popup=SIGDEMO1_DAT(11);
    t=SIGDEMO1_DAT(14:14+N-1);
    window=SIGDEMO1_DAT(14+N:14+N+N-1);
    val = get(popup,'Value');
    if (val == 1),
        f=amp*cos(freq*t*2*pi);
    elseif (val == 2),   % square wave
        tt=freq*t*2*pi;
        tmp=rem(tt,2*pi);
        f=amp*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
    elseif (val == 3),   % sawtooth
        tt=freq*t*2*pi;
        f=amp*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
    end;
    set(time_line,'YData',f);
    F=fft(window.*f,2*M);
    F=F(1:M);
    w=(0:M-1)*pi/M;
    FF=20*log10(abs(F));
    ind=find(FF<min_dB);
    FF(ind)=NaN*ones(size(ind)); % put NaN's in where
             % min_dB shows up - this is to work around no clipping in xor mode
    set(freq_line,'YData',FF);
    set(freq_field,'String',num2str(freq));

    drawnow;

elseif strcmp(action,'setwindow'),
    % u = get(gcf,'userdata');
    N=SIGDEMO1_DAT(3);
    if (in1==1),
        window = boxcar(N);
    elseif (in1==2),
        window = triang(N);
    elseif (in1==3),
        window = hanning(N);
    elseif (in1==4),
        window = hamming(N);
    elseif (in1==5),
        window = chebwin(N,in2);
    elseif (in1==6),
        window = kaiser(N,in2);
    end;
    SIGDEMO1_DAT(14+N:14+N+N-1)=window;
    % set(gcf,'userdata',u);
    sigdemo1('redraw');
    if (SIGDEMO1_DAT(12)~=-1),
        sigdemo1('showwind');
    end;

elseif strcmp(action,'showwind'),
    % u=get(gcf,'userdata');
    oldfig=gcf;
    N=SIGDEMO1_DAT(3);
    t=SIGDEMO1_DAT(14:14+N-1);
    window=SIGDEMO1_DAT(14+N:14+N+N-1);
    if (SIGDEMO1_DAT(12)==-1),
        SIGDEMO1_DAT(12)=figure;

        axes('Position',[.15 .62 .8 .3]);
        line1=plot(t,window); 
        title('Window function');
        xlabel('time (seconds)');
        grid;
        ylabel('Window');

        axes('Position',[.15 .2 .8 .3]);
        W=fft(window,1024);
        line2=plot((0:(1/1024):(.5-(1/1024)))*N,20*log10(abs(W(1:512)))); 
        set(gca,'xlim',[0 N/2]);
        xlabel('Frequency (Hz)');
        ylabel('Magnitude (dB)');
        grid;
        windclose=uicontrol('Style','Pushbutton','Position',[.85 .02 ...
            .12 .08],...
            'Units','normalized','Callback',['THEHAND=get(gcf,''userdata'');'...
            'close; figure(THEHAND(1)); global SIGDEMO1_DAT, '...
            'SIGDEMO1_DAT(12)=-1; clear THEHAND SIGDEMO1_DAT'],'String','Close');
        set(gcf,'userdata',[oldfig line1 line2]);
        % set(oldfig,'userdata',u);
        
    else
        figure(SIGDEMO1_DAT(12));
        lines=get(gcf,'userdata');
        set(lines(2),'ydata',window);
        W=fft(window,1024);
        set(lines(3),'ydata',20*log10(abs(W(1:512))));
        drawnow
    end

elseif strcmp(action,'setfreq'),
    % u = get(gcf,'userdata');
    SIGDEMO1_DAT(1)=str2num(get(SIGDEMO1_DAT(10),'string'));
    % set(gcf,'userdata',u);

end

