function detuning(action)
%detuning A demonstration of detuned harmonics
%
% My first MAD demo, slightly modified from STREAMER
%
% 1998jul11 dpwe@icsi.berkeley.edu
% updated July 1999 by Martin for v2.1

if nargin < 1
  action='init'; 
end

switch action

case 'init'
  % does main figure window exist? If so, bring it to front
  f=findobj('Tag','detuning_fig');
  if ~isempty(f)
    figure(f);
  else
    detuning_gui;		         % otherwise, create one
    ud=get(gcf,'UserData');
    ud.cycles=3;
    % ud.sr = 22050;
    ud.sr = 8012;   % modified by MPC to allow for more platforms
	ud.f0 = 250;
    ud.detuneNum = 4;
	ud.dur = 200;
	ud.totHs = 6;
	ud.onset = 0;
    ud.expectingKey=0;
    % Moore's data (currently made up)
    ud.std=line([-9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9],...
    [-.05 -.1 -.18 -.25 -.32 -.38 -.4 -.35 -.2 0 0.2 0.35 0.4 0.38 0.32 0.25 0.18 0.1 0.05],'Visible','off','LineWidth',3,'LineStyle','--');
    set(gcf,'UserData',ud); 
  end
    
  case 'showexpt'
    ud=get(gcf,'UserData');
    if get(gco,'Value')
      set([ud.std],'Visible','on');
    else  
      set([ud.std],'Visible','off');
    end
  
  case 'numCyclesChanged'
    ud=get(gcf,'UserData');
	vlist=get(findobj('Tag','numCyclesMenu'),'String');
	vstr=vlist(get(findobj('Tag','numCyclesMenu'),'Value'));
	ud.cycles = str2num(char(vstr));
    set(gcf,'UserData',ud);	
	
    
  case 'misHChanged'
    ud=get(gcf,'UserData');
	vlist=get(findobj('Tag','detuneMisHMenu'),'String');
	vstr=vlist(get(findobj('Tag','detuneMisHMenu'),'Value'));
	ud.detuneNum = str2num(char(vstr));
    set(gcf,'UserData',ud);	
	
  case 'nHarmsChanged'
    ud=get(gcf,'UserData');
	vlist=get(findobj('Tag','detuneNHarmMenu'),'String');
	vstr=vlist(get(findobj('Tag','detuneNHarmMenu'),'Value'));
	ud.totHs = str2num(char(vstr));
    set(gcf,'UserData',ud);	

  case 'f0SliderChanged'
		ud=get(gcf,'UserData');
		ud.f0=round(get(findobj('Tag','f0Slider'),'Value'));
		set(findobj('Tag','f0Box'),'String',num2str(ud.f0));
		set(gcf,'UserData',ud);
		
  case 'f0BoxChanged'
		ud=get(gcf,'UserData');
		ud.f0=str2num(get(findobj('Tag','f0Box'),'String'));
		set(findobj('Tag','f0Slider'),'Value',ud.f0);
		set(gcf,'UserData',ud);
	
  case 'durSliderChanged'
		ud=get(gcf,'UserData');
		ud.dur=round(get(findobj('Tag','durSlider'),'Value'));
		set(findobj('Tag','durBox'),'String',num2str(ud.dur));
		set(gcf,'UserData',ud);

  case 'durBoxChanged'	
		ud=get(gcf,'UserData');
		ud.dur=str2num(get(findobj('Tag','durBox'),'String'));
		set(findobj('Tag','durSlider'),'Value',ud.dur);
		set(gcf,'UserData',ud);
	
  case 'onsSliderChanged'
		ud=get(gcf,'UserData');
		ud.onset=round(get(findobj('Tag','onsSlider'),'Value'));
		set(findobj('Tag','onsBox'),'String',num2str(ud.onset));
		set(gcf,'UserData',ud);

  case 'onsBoxChanged'	
		ud=get(gcf,'UserData');
		ud.onset=str2num(get(findobj('Tag','onsBox'),'String'));
		set(findobj('Tag','onsSlider'),'Value',ud.onset);
		set(gcf,'UserData',ud);
	
  case 'generate'
    title('Hit "p" if pitches match; Click again to repeat');
    cp=get(gca,'CurrentPoint');
    ud=get(gcf,'UserData');
    ud.detune=cp(1);
    ud.match=cp(3);
    ud.expectingKey=1;
    % generate detuned tone
	y1 = detunex(ud.detune/100, -ud.onset/1000, ud.detuneNum, ud.f0, ud.dur/1000, ud.totHs, ud.sr);
    % generate matching tone
	y2 = detunex(0,-ud.onset/1000, 0*ud.detuneNum, (1+ud.match/100)*ud.f0, ud.dur/1000, ud.totHs, ud.sr);
    % Generate alternating stim
    gap=zeros(1,round(ud.sr*0.15));
	% Leave a longer gap after the matching tone
    onecycle=[y1, gap, y2, gap, gap]';
    % allcycles=zeros(ud.cycles,length(onecycle));
    o=ones(1,ud.cycles);
    allsig=onecycle(:,o);
    allsig=allsig(:);
    allsig=0.1*(allsig/max(allsig));
    sound(allsig(:),ud.sr);	  
    set(gcf,'UserData',ud);
    
  case 'keypressed'
    ud=get(gcf,'UserData');
    if (ud.expectingKey==1)
      % expecting a press
      if (get(gcf,'CurrentCharacter')=='p')
        % pitch match
        hold on;
        plot(ud.detune,ud.match,'ro','EraseMode','xor');
      end
      ud.expecting=0;
      set(gcf,'UserData',ud);
      title('Click in the grid to hear a tuned/detuned alternation');
    end
 
otherwise
  maduievent('detuning',action);
   
  
  end
  
