function ti(action)
%TI Demonstration of auditory temporal induction.
%
% 
%
% Martin Cooke, May 1998
%  Updated June 1998 for first release of M.A.D.
%  updated July 1999 for v2.1
%
% Future enhancements:
%  proper support for CVC type induction
%  avoid use of signal processing toolbox

if nargin < 1
  action='init';
end

switch action

case 'init'
  % does main figure window exist? if so, bring it to front
  f=findobj('Tag','ti_fig');
  if ~isempty(f)
    figure(f);
  else
    savedir=pwd;  
    ti_gui;		% create one
    ud=get(gcf,'UserData');
    ud.fs=8192;
    ud.len=2;    % seconds
    ud.siglevel=60;
    ud.savedir=savedir;
    ud.path=fullfile(madroot,'ti','');
    colormap(hot.*gray);  % a rather fine sepia
    set(gcf,'Name','no data loaded');
    set(gcf,'UserData',ud);
  end

  case 'create'
  [sig,fs,name]=createsig;
  if length(sig)
    ud=get(gcf,'UserData');
    ud.sig=sig; ud.name=name; ud.fs=fs; 
    set(gcf,'UserData',ud);
    ti 'newsig'
  end
  
case 'load'
  ud=get(gcf,'UserData');
  [name,sig,fs]=loadsig(fullfile(madroot,'data','sounds'));
  if length(sig) 
    ud.sig=sig; ud.name=name; ud.fs=fs; 
    set(gcf,'UserData',ud);
    ti 'newsig'
  end

case 'preset'
  ud=get(gcf,'UserData');
  sourcetype=get(gcbo,'Label');
  loaded=1;
  ud.fs=8192;
  switch sourcetype
  
  case 'tone'
    ud.sig=tone(1000,60,1000*ud.len,ud.fs);
    
  case 'siren'
    t=1:(ud.fs*ud.len);
    mf=1;  % mod freq
    c=1+sin(2*pi*mf*t/ud.fs);
    c=500+1500*c;
    ud.sig=sin(2*pi*cumsum(c)/ud.fs);
        
  case 'speech'
    [f,p]=uigetfile(fullfile(madroot,'data','sounds','*.au'),'choose a file');
    if f
      [ud.sig,ud.fs,bits]=auread([p f]);
      ud.sig=ud.sig';
    else 
      loaded=0;  
    end
  
  case 'music'
    [f,p]=uigetfile(fullfile(madroot,'data','sounds','*.music'),'choose a file');
    if f
      [ud.sig,ud.fs,bits]=auread([p f]);
      ud.sig=ud.sig'; 
    else
      loaded=0;  
    end 
  
  case 'narrowbandnoise'
    bw=200;
    lf=max(1,ud.cf-(bw/2));
    hf=min(ud.fs/2.5,ud.cf+(bw/2));
    [b,a]=butter(4,2*[lf hf]./ud.fs);
    ud.sig=filter(b,a,rand(1,ud.fs*ud.len));	
    
  case 'broadbandnoise'
    bw=1000;
    lf=max(1,ud.cf-(bw/2));
    hf=min(ud.fs/2.5,ud.cf+(bw/2));
    [b,a]=butter(4,2*[lf hf]./ud.fs);
    ud.sig=filter(b,a,rand(1,ud.fs*ud.len));	
  
  end
  
  if loaded  
    ud.name=sourcetype;  
    set(gcf,'UserData',ud);
    ti 'newsig'
  end

case 'newsig'
  ud=get(gcf,'UserData');
    set(ud.testAxes,'ButtonDownFcn','ti generate');
    set(gcf,'Name',['temporal induction on: ' ud.name]);
    set(findobj('Tag','noisecf'),'Enable','on');
    set(findobj('Tag','noisebw'),'Enable','on');
    ud.sig=ud.sig(:)';
    % normalise signal to be at 60dB where 80dB=1
    ud.sig=ud.sig.*(db2amp(60,80)/max(ud.sig));
    ud.mix=ud.sig;
    sg=spectrogram(ud.mix,ud.fs,30,5);  
    axes(ud.spectAxes);
    ud.spectim=imagesc(sg');
    set(ud.spectim,'ButtonDownFcn','ti play');
    [frames,chans]=size(sg);
    set(ud.spectAxes,'XLim',[1 frames],'YLim',[1 chans]);     
    ud.maxlevel=max(sg(:));
    set(gcf,'UserData',ud);
    ti 'recalc'

case 'noisecfchanged'
  ud=get(gcf,'UserData');
  ud.cf=str2num(get(gcbo,'Label'));
  set(findobj('Tag','noisecf'),'Checked','off');
  set(gcbo,'Checked','on');
  set(gcf,'UserData',ud);
  ti 'recalc'
  
case 'recalc'
  ud=get(gcf,'UserData');
  if ud.fullband
    ud.noise=rand(1,length(ud.sig));
  else
    ud.lf=max(1,ud.cf-(ud.bw/2));
    ud.hf=min(ud.fs/2.5,ud.cf+(ud.bw/2));
    [b,a]=butter(4,2*[ud.lf ud.hf]./ud.fs);
    % create a few seconds worth of noise to dip into
    ud.noise=filter(b,a,rand(1,length(ud.sig)));
  end
  set(gcf,'UserData',ud);
  
  
case 'noisebwchanged'
  ud=get(gcf,'UserData');
  s=get(gcbo,'Label');
  if strcmp(s,'full band')
    ud.fullband=1;
  else
    ud.fullband=0;	
    ud.bw=str2num(s);
  end
  % recalc noise?
  set(findobj('Tag','noisebw'),'Checked','off');
  set(gcbo,'Checked','on');
  set(gcf,'UserData',ud);
  ti 'recalc'
  
case 'repeatschanged'
  ud=get(gcf,'UserData');
  ud.repeats=get(gcbo,'Label');
  
  set(findobj('Tag','repeats'),'Checked','off');
  set(gcbo,'Checked','on');
  set(gcf,'UserData',ud);	
  
case 'visualise_spect'
  ud=get(gcf,'UserData');
  axes(ud.spectAxes);
  sg=spectrogram(ud.mix,ud.fs,30,5);
  set(ud.spectim,'CData',sg');
  drawnow
  
case 'generate'
  cp=get(gca,'CurrentPoint');
  ud=get(gcf,'UserData');
  ud.dur=cp(1);
  ud.level=cp(3);
  set(ud.cp,'XData',ud.dur,'YData',ud.level);
  durs=round((ud.fs/1000)*ud.dur);  % duration in samples
  
  % generate the signal
  
  
  slen=length(ud.sig);
  z=zeros(1,slen);
  
  switch ud.repeats
  case 'once'
    st=round(rand(1)*(slen-durs));
    fin=st+durs-1;
    z(st:fin)=1;
    
  case 'regular'
    % off for durs, on for durs, ...
    st=durs+1;
    while (st+durs) < slen
      fin=st+durs-1;
      z(st:fin)=1;
      st=st+2*durs;
    end
  
  case 'random'
    % decide how many to have
    n=round(slen/(2*durs));
    sts=round(slen*rand(1,n));
    fins=min(slen,sts+round(2*durs*rand(1,n)));
    for i=1:n	  
      z(sts(i):fins(i))=1;
    end
  
  end

  % determine multiplier for the noise as a fn of time
  
  m=db2amp(60+ud.level,80);
  ud.mix=(((1-z).*ud.sig) + z.*m.*ud.noise);
  %sound(ud.mix,ud.fs);
  
  ud.expecting=1;
  set(gcf,'UserData',ud);
  
  % if show spectrogram
  ti 'visualise_spect'
  ti 'play'
  
case 'play'
  ud=get(gcf,'UserData');
  sound(ud.mix,ud.fs)
  
case 'saveSignal'
	ud=get(gcf,'UserData');
	[f,p] = uiputfile('mix.au','Select filename to save signal');
	if f
    if isfield(ud,'mix')  % data is loaded
      s=ud.mix;
      s=s/max(abs(s));
	    auwrite(s,ud.fs,[p f]);
    end  
  end


case 'reallyquit'
  ud=get(gcf,'UserData');
  cd(ud.savedir);
  delete(get(0,'CurrentFigure'));
    
otherwise
  maduievent('ti',action);

  
end

%----------------------------------
function z=dBadd(x,y)
% add x and y on a dB scale
z=amp2dB(db2amp(x)+db2amp(y));

