function GUIfilter(fcn)

%demo of user interface construction
%this function CALLS ITSELF via GUI callbacks

% By default make the GUI
%This code detects the first entry into the function
%from the command line with no parameters
if nargin == 0
   fcn = 'makeGUI';
end

%This is the main decision point of the function.
%The switch statement is executed once-per-fuction call
switch fcn
   
   %This code is executed ONCE when the function enters with
   %no arguments
case 'makeGUI'
   data=[];
   data.myname = mfilename;
   data = buildGUI(data);         %build the interface
   data = choosewave(data); %make the default waveform
   data = choosefil(data);  %make the default filter
   plotItAll(data);
   
case 'quit'
   fig = gcbf;
   %quit_reply = questdlg('Really quit this lame program?');
   %if strcmp(quit_reply,'Yes')
   close(fig);
   %end
   
case 'chooseinput'
   data = get(gcbf,'userdata');
   data = choosewave(data);
   data = choosefil(data);
   plotItAll(data);   
   set(gcbf,'UserData',data);
   
case 'choosefilter'
   data = get(gcbf,'userdata');
   data = choosewave(data);
   data = choosefil(data);
   plotItAll(data);   
   set(gcbf,'UserData',data);

end %of main function switch


%=== Fuction to build the interface ====================
function data=buildGUI(data)

% Create main figure==========================
data.fig = figure('Position',centerfig(600,600),...
   'Resize','off',...
   'NumberTitle','off',...
   'Name','GUI filter demo',...
   'Interruptible','off',...
   'Color',get(0,'DefaultUIControlBackgroundColor'));

% The axes======================================= 
data.axes=...
   axes('Units','pixels',...
   'Position',[50 165 500 360],...
   'Box','on', ...
   'XLim',[0 .1],'YLim',[0 2]);

% The quit button===============================
uicontrol('Style','pushbutton',...
   'Position',[550 550 45 25],...
   'String','Quit',...
   'Interruptible','off',...
   'BusyAction','cancel',...
   'Callback',[data.myname,' quit']);

% frames for input settings ===============
uicontrol(gcf,'style','frame', ...
   'Position',[25,535,250,60],...
   'BackgroundColor',[.8,.8,.8]);

% title for input settings ===============
uicontrol(gcf,'style','text', ...
   'string', 'Input wave', ...
   'fontsize',14, ...
   'Position',[110,565,100,25],...
   'BackgroundColor',[.8,.8,.8]);

% Input Chooser=========================
data.inchoose=uicontrol(gcf,'Style','listbox', ...
   'String','pulse|chirp|mepp',...
   'Position',[30,540,70,50],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' chooseinput'] );

% noise button===================================
data.noise=uicontrol(gcf,'Style','checkbox', ...
   'String','Noise',...
   'Position',[120,540,70,20],...
   'BackgroundColor',[1,1,1], ...
   'value', 0, ...
   'CallBack',[data.myname,' chooseinput'] );

% noise size====================================
data.noisegain=uicontrol(gcf,'Style','edit', ...
   'String','0.15',...
   'Position',[180,540,70,20],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' chooseinput'] );

% frames for filter settings ===============
uicontrol(gcf,'style','frame', ...
   'Position',[30,30,450,100],...
   'BackgroundColor',[.8,.8,.8]);

% title for filter settings ===============
uicontrol(gcf,'style','text', ...
   'string', 'Filter Parameters', ...
   'fontsize',14, ...
   'Position',[90,40,200,30],...
   'BackgroundColor',[.8,.8,.8]);

% passband freq ===============================
data.cutoff=uicontrol(gcf,'Style','edit', ...
   'String','0.1',...
   'Position',[35,80,70,20],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

uicontrol(gcf,'Style','text', ...
   'String','Passband', ...
   'Position',[35,100,70,20], ...
   'BackgroundColor',[.8,.8,.8] );

% number of poles ===============================
data.poles=uicontrol(gcf,'Style','edit', ...
   'String','4',...
   'Position',[120,80,70,20],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

uicontrol(gcf,'Style','text', ...
   'String','Filter Size', ...
   'Position',[120,100,70,20], ...
   'BackgroundColor',[.8,.8,.8] );

% ripple ===============================
data.ripple=uicontrol(gcf,'Style','edit', ...
   'String','.1',...
   'Position',[200,80,70,20],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

uicontrol(gcf,'Style','text', ...
   'String','Ripple in db', ...
   'Position',[200,100,70,20], ...
   'BackgroundColor',[.8,.8,.8] );

% stopband freq ===============================
data.stop=uicontrol(gcf,'Style','edit', ...
   'String','0.15',...
   'Position',[280,80,70,20],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

uicontrol(gcf,'Style','text', ...
   'String','Stopband', ...
   'Position',[280,100,70,20], ...
   'BackgroundColor',[.8,.8,.8] );

% filter Chooser=========================
data.filchoose=uicontrol(gcf,'Style','listbox', ...
   'String','Butterworth|Chebyshev|Parks-McCellan',...
   'Position',[375,50,100,50],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

% plot mode Chooser=========================
data.plotmode=uicontrol(gcf,'Style','listbox', ...
   'String','Time|Frequency',...
   'Position',[375,540,100,50],...
   'BackgroundColor',[1,1,1], ...
   'CallBack',[data.myname,' choosefilter'] );

%put all the data in a safe place (the figure's data area)
set(data.fig,'UserData',data);

%====================================================
%=== A utility to center the window on the screen ===
function pos = centerfig(width,height)

% Find the screen size in pixels
screen_s = get(0,'ScreenSize');
pos = [screen_s(3)/2 - width/2, screen_s(4)/2 - height/2, width, height];

%====================================================
%=== Set the input waveform =========================
function data=choosewave(data)

i=get(data.inchoose,'value');
data.time = linspace(0,.1,1000);

switch i 
   
case 1 %pulse  
   data.waveform = (data.time>.02 & data.time<.07);  
case 2 %chirp
   data.waveform =  chirp(data.time,10,.1,1000);
case 3 %mepp
   data.waveform = 550 * (data.time-.01) ... 
      .* exp(-(data.time-.01)/.005) ...
      .* (data.time > .01);
end

if (get(data.noise,'value'))
   data.waveform = data.waveform + ...
      str2num(get(data.noisegain,'string'))*...
      randn(size(data.time));
end

%====================================================
%=== choose filter =================================
function data=choosefil(data);

%get the filter type from the list
i=get(data.filchoose,'value');

%get cutoff and check range
cutoff=str2num(get(data.cutoff,'string'));
if cutoff>=1
   cutoff=.99;
   set(data.cutoff,'string',num2str(cutoff));
end
if cutoff<=0
   cutoff=.01;
   set(data.cutoff,'string',num2str(cutoff));
end

%get stopband and check range
cuton=str2num(get(data.stop,'string'));
if cuton>=1
   cuton=.99;
   set(data.stop,'string',num2str(cuton));
end
if cuton<=0
   cuton=.01;
   set(data.stop,'string',num2str(cuton));
end
if cuton<=cutoff
   cuton=cutoff+.01;
   set(data.stop,'string',num2str(cuton));
end

numpole=fix(str2num(get(data.poles,'string')));
set(data.poles,'string',num2str(numpole));

ripple=str2num(get(data.ripple,'string'));


switch i 
   
case 1 %butterworth  
   [b,a]=butter(numpole,cutoff) ; 
   set(data.ripple,'enable','off');
   set(data.stop,'enable','off');
case 2 %chebychev
   [b,a]=cheby1(numpole,ripple,cutoff);
   set(data.ripple,'enable','on');
   set(data.stop,'enable','off');
case 3 %parks-mcCellan
   freq = [0 cutoff cuton 1]; 
   amp = [1 1 0 0];
   b = remez(numpole,freq,amp);
   a = [ 1 zeros(length(b)-1,1)'];  
   set(data.ripple,'enable','off');
   set(data.stop,'enable','on');
end

data.wavefil = filter(b,a,data.waveform); 
[data.fresponse, data.ffreq] = freqz(b,a,100);

%====================================================
%=== make the plots =================================
function data=plotItAll(data);

hold off 

if (get(data.plotmode,'value')==1)
   plot(data.time, data.waveform, 'b', 'linewidth',2);
   hold on
   plot(data.time, data.wavefil,'r', 'linewidth',2);
   xlabel('time'); ylabel('voltage');
   legend('input','filtered output');
else
   plot(data.ffreq/pi, ...
      abs(data.fresponse), ...
      'b', 'linewidth',2);
   xlabel('frequency'); ylabel('filter amplitude');
   
end
   

   