%%%%%%%EOD Simulator by Joel Avrunin%%%%%%%%%%%%

function eodsim(fcn)
   global wavenum;
   global wavetime; %%interval base for waves
   global wave;     %%wave amplitude data
   global time;     %%wave time axis
   global s_rate;   %%sampling rate
   global inputfile;
   global wavenum;
   global fn;
%   global wave_text;
%   global t1;
%   global t2
%   global ax;
   global equalzero;
   global number_entries; %%number of entries in the wave sample
   global realtime; %the length of the sound byte in realtime
   global pointone; %%0 matrix of length 0.1 s
   global int_mean;
   global sd;
   global min_interval;
%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'
   plotinfo.myname = mfilename;

   fig = figure('Position',centerfig(760,630),...
      'Resize','off',...
      'NumberTitle','off',...
      'Name','EOD Generator',...
      'Interruptible','off',...
      'Menubar','none',...
      'Color',get(0,'DefaultUIControlBackgroundColor'));
   
   %===Title text===================================
   uicontrol(gcf,'Style','text', ...
      'String','EOD Generator',...
      'fontsize',24, ...
      'HorizontalAlignment','Center',...
      'Position',[190,580,270,30],...
      'BackgroundColor',[0.8 1 0.8]);
   
   uicontrol(gcf,'Style','text', ...
      'String','by Joel Avrunin',...
      'fontsize',12, ...
      'HorizontalAlignment','Center',...
      'Position',[440,580,100,30],...
      'BackgroundColor',[0.8 1 0.8]);
   
   %%%%Button List Titles
   
   uicontrol(gcf,'Style','text', ...
      'String','File Access',...
      'fontsize',10, ...
      'HorizontalAlignment','Center',...
      'Position',[10,200,70,20],...
      'BackgroundColor',[0.52 0.90 0.97]);
   
   uicontrol(gcf,'Style','text', ...
      'String','Wave Controls',...
      'fontsize',10, ...
      'HorizontalAlignment','Center',...
      'Position',[10,110,100,20],...
      'BackgroundColor',[0.52 0.90 0.97]);
   
   uicontrol(gcf,'Style','text', ...
      'String','Output',...
      'fontsize',10, ...
      'HorizontalAlignment','Center',...
      'Position',[240,200,70,20],...
      'BackgroundColor',[0.52 0.90 0.97]);
   
   uicontrol(gcf,'Style','text', ...
      'String','Input',...
      'fontsize',10, ...
      'HorizontalAlignment','Center',...
      'Position',[240,110,70,20],...
      'BackgroundColor',[0.52 0.90 0.97]);
   
   uicontrol(gcf,'Style','text', ...
      'String','Interval Statistics',...
      'fontsize',10, ...
      'HorizontalAlignment','center',...
      'Position',[440,200,140,20],...
      'BackgroundColor',[0.52 0.90 0.97]);
   
   %Define fields for generating timebase on mean intervals
   uicontrol('style','text',...
   'string','mean=',...
   'HorizontalAlignment','right',...
   'fontsize',10, ...
   'position',[410,170,100,20]);

  uicontrol('style','text',...
   'string','S.D.=',...
   'HorizontalAlignment','right',...
   'fontsize',10, ...
   'position',[410,140,100,20]);

  uicontrol('style','text',...
   'string','Min. Inteval=',...
   'HorizontalAlignment','right',...
   'fontsize',10, ...
   'position',[410,110,100,20]);
   
   %define the open waveform button
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Open Waveform',...
      'Position',[10,170,100,20],...
      'BackgroundColor',[0.8,0.8,0.8], ...
      'CallBack',[plotinfo.myname,' openmwv'] );
   
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Save Waveform',...
      'Position',[10,150,100,20],...
      'BackgroundColor',[0.9 0.9 0.9], ...
      'CallBack',[plotinfo.myname,' savemwv'] );
   
      %==Draw button===========================
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Generate Random Timebase',...
      'Position',[10,80,150,20],...
      'BackgroundColor',[0.8,0.8,0.8], ...
      'CallBack',[plotinfo.myname,' gentime'] );
   
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Generate Based on Mean',...
      'Position',[10,60,150,20],...
      'BackgroundColor',[0.8,0.8,0.8], ...
      'CallBack',[plotinfo.myname,' meantime'] );
   
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Quit',...
      'Position',[600,590,100,30],...
      'BackgroundColor',[0.8,0.8,0.8], ...
      'CallBack',[plotinfo.myname,' quit'] );
   
         %==Draw button===========================
   uicontrol(gcf,'Style','Pushbutton', ...
      'String','Follow timebase',...
     'Position',[240,170,100,20],...
     'BackgroundColor',[0.8,0.8,0.8], ...
     'CallBack',[plotinfo.myname,' playwave'] );
   
  uicontrol(gcf,'Style','Pushbutton', ...
     'String','Continuous Tenths',...
     'Position',[240,150,100,20],...
     'BackgroundColor',[0.8,0.8,0.8], ...
     'CallBack',[plotinfo.myname,' playcont'] );
  
  uicontrol(gcf,'Style','Pushbutton', ...
     'String','Read Waveform',...
     'Position',[240,80,100,20],...
     'BackgroundColor',[0.8,0.8,0.8], ...
     'CallBack',[plotinfo.myname,' readwave'] );
   
   % ===Create axes=================================
   plotinfo.ax = axes('Units','pixels',...
      'Position',[450 260 296 270],...
      'Box','on',...
      'XLim',[-2 2],'YLim',[-1 1]);
   xlabel('t (msec)'); ylabel('v (mV)');
   
   % ===Create axes=================================
   plotinfo.ax2 = axes('Units','pixels',...
      'Position',[50 395 325 135],...
      'Box','on',...
      'XLim',[0 10],'YLim',[-1 1]);
   xlabel('t (tenths of a sec)');
   
   set(fig,'UserData',plotinfo);
   
case 'openmwv'
   plotinfo=get(gcf,'UserData');   
   [fn pn]=uigetfile('f:\classes\research\*.eod','Open input file...');
													%opens file open dialog box;
													%fn=filename, pn=pathname
   inputfile = [pn fn];							%assigns variable inputfile to file name
   fid = fopen(inputfile, 'r');				%opens file, for 'r' read only
													%fid is an integer file identifier
   [version,count]=fread(fid,1,'char');	%reads binary data from opened file fid
													%writes it into matrix version, here '1'=1x1
                                       %precision is 'char'=8 bit
													%out argument count is #elements success read                                       
   if(count == 0)
	   fprintf (1,'%s %d\n', 'Error on read, end of file, count = ',count)
													%FID=1 (standard output); \n (linefeed)
      return;										%causes return to invoking function or keyboard
   end												%terminates scope of IF statement

   wavenum=0;										%start with first EOD in file
   nchar_text=fread(fid,1,'short');			%size of text info (precis short=integer 16bit)
   temp=fread(fid,nchar_text,'char');		%integer representation of text info
   wave_text=sprintf('%c',temp);				%writes %c formatted data to string wave_text
   n_bits=fread(fid,1,'char');				%?bits of vertical resolution?
   n_bytes=fread(fid,1,'char');				%?size of file?
   data_polarity=fread(fid,1,'char');		%determined by user at time of recording
   user_data=fread(fid,6,'float');			%six user defn, usu unused floating pnts 32bit
   s_rate=fread(fid,1,'ulong');				%sampling rate of eod; unsigned long int 32 or 64 bit
   adrange=fread(fid,1,'float');				%?raw voltage range?
   n_pts=fread(fid,1,'long');					%number of points in eod sample
   wave=fread(fid,n_pts,'short');			%eod voltage data
   time=linspace(0,1000*n_pts/s_rate,n_pts);	%eod time data in milliseconds
   
   
   


   %%%%%%%%%%
   %normeodp1.m
   %normalizes a wave to 0 baseline voltage
   %1.0 peak to peak voltage difference
   %and centers the time base on P1
   %%%%%%%%%%
   
   baseline = mean(wave(1:20));
   wave = wave-baseline;
   [ymax,ivmax] = max(wave);
   [ymin,ivmin] = min(wave);
   wave = wave/(ymax-ymin);
   time = time - (time(ivmax));
   
      
   %%%%%%%%%%%%
   %%Resample the signal down to 44 KHz
   %%%%%%%%%%%%
   sfactor=s_rate/1000;               %% drop the sampling rate by factor of 1000
   prate=44;                          %% This is the 44 KHz sampling rate required for sound card output
   qrate=sfactor;
   wave=resample(wave,prate,qrate);   %%resamples wave by factor of p/q
   number_entries=size(wave);         %%required to manually recalculate new timebase
   number_entries=number_entries(1);
   maxtime=size(time);
   maxtime=maxtime(2);
   accum_num=(time(maxtime)-time(1))/number_entries;
   
   %%calculate the new time spacing for resampled signal
   
   accum=time(1);
   time=[];
   
   for x=1:number_entries             %%loop creates new time matrix
      time=[time accum];
      accum=accum+accum_num;
   end;
   
   if time(1)<-2                 %%truncate long time signals to right length
   
      for x=1:number_entries
         if time(x)<-2
            lowhold=x; %%save bottom value at t=-2 ms
         end;
         if time(x)<2
            highhold=x; %%saves top value at t=2 ms
         end;
      end;
   
   
      %Truncate wave into 4 ms frame
      wave=wave(lowhold:highhold);
      time=time(lowhold:highhold);
   end;
   %%%%%%%%%%
   %%Calculate realtime length of sound
   sound_length=length(time);
   realtime=sound_length/44000;
   
   %%%%%%%%%%
   %plotwave.m
   %plots current wave and labels it
   %%%%%%%%%%
   figure(1);
 
   set(gcf,'currentaxes',plotinfo.ax) 
   plot(time,wave);
   axis([-2 2 -1 1]);
   xlabel('t (msec)'); ylabel('v (mV)');
   title([fn '  ' num2str(wavenum)],'fontsize',10);
   
   %text(t1+.02*(t2-t1),ax(3)+0.97*(ax(4)-ax(3)),wave_text((1):round(7*lt/12)),'fontsize',8);
   uicontrol(gcf,'Style','text', ...
      'String',wave_text,...
      'fontsize',12, ...
      'HorizontalAlignment','Center',...
      'Position',[20,280,350,50],...
      'BackgroundColor',[0.8 1 0.8]);
      
   
case 'gentime' %%This code generates a random timebase for the signal
   plotinfo=get(gcf,'UserData');
   wavetime=[ ];
   
   onesix=randperm(6);
   onesix=onesix(1);
   
   for x=0:9
      onesix=randperm(6); %%random number from 1 to 6
      onesix=onesix(1);   %%select first in matrix of 1 to 6
      if onesix==1 %%select one of six random pulse patterns
         wavetime=[wavetime;1;1;1;1;1;1;1;1;1;1];
      elseif onesix==2
         wavetime=[wavetime;1;0;1;0;1;0;1;0;1;0];
      elseif onesix==3
         wavetime=[wavetime;1;0;0;1;0;0;1;0;0;1];
      elseif onesix==4
         wavetime=[wavetime;1;0;0;0;1;0;0;0;1;0];
      elseif onesix==5
         wavetime=[wavetime;1;0;0;0;0;1;0;0;0;0];
      elseif onesix==6
         wavetime=[wavetime;1;0;0;0;0;0;0;0;0;0];
      end
   end
   
   set(gcf,'currentaxes',plotinfo.ax2) ;
   cla;
   axis([0 100 -1 1]);
   for n=1:100 %%plots timing on graph
      if wavetime(n)==1 line([n;n],[-1;1]);
         end
   end
   
   
case 'meantime' %Generate based on mean, sd, and minimum interval
   plotinfo=get(gcf,'UserData');
   wavetime=[ ];
   %%display prompt for entering statistical data
   prompt={'Mean','Standard Deviation','Minimum Interval'};
   defans={'0.6','0.25','0.1'};
   fields={'meanA','sdA','min_intervalA'};
   info=inputdlg(prompt,'Enter the information',1,defans);
   if ~isempty(info)
      info = cell2struct(info,fields);
      int_mean = str2num(info.meanA);
      sd = str2num(info.sdA);
      min_interval = str2num(info.min_intervalA);
   end
   
   uicontrol(gcf,'Style','text', ...
      'String',info.meanA,...
      'fontsize',12, ...
      'HorizontalAlignment','Center',...
      'Position',[520,170,45,20],...
      'BackgroundColor',[1 0.65 1]);
   uicontrol(gcf,'Style','text', ...
      'String',info.sdA,...
      'fontsize',12, ...
      'HorizontalAlignment','Center',...
      'Position',[520,140,45,20],...
      'BackgroundColor',[1 0.65 1]);
   uicontrol(gcf,'Style','text', ...
      'String',info.min_intervalA,...
      'fontsize',12, ...
      'HorizontalAlignment','Center',...
      'Position',[520,110,45,20],...
      'BackgroundColor',[1 0.65 1]);
   wavetime=zeros(100,1);
   wavetime(1)=1;
   i=1;
   %%create intervals base on this random on the normal curve
   while i<101
      interval=round(max(int_mean+sd*randn,min_interval)*10);
      i=i+interval; %%increment by random interval just calculated
      wavetime(i)=1;
   end
  
   set(gcf,'currentaxes',plotinfo.ax2) ;
   cla;
   axis([0 100 -1 1]);
   for n=1:100 %%plots timing on graph
      if wavetime(n)==1 line([n;n],[-1;1]);
         end
   end

   
   
case 'quit'
   fig = gcf;
   quit_reply = questdlg('Really quit EODSIM?');
   if strcmp(quit_reply,'Yes')
      close(fig);
   end
   
case 'playcont'
   for j=1:10
      wavplay(wave,44000,'sync'); %%synchronous to prevent errors in reopening sound device
%      pause(0.1);
      wavplay(pointone,44000,'sync'); %%0.1 s wait
   end

case 'playwave' %outputs the wave
   pointone=zeros(1,4400);
   pointohone=zeros(1,440);
   
   for j=1:100
      if wavetime(j)==1
         wavplay(wave,44000,'sync');
         wavplay(pointone,44000,'sync');
      else wavplay(pointone,44000,'sync');
      end
   end      
end
return

%===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];
return
