function vowelSeg(action)
%VOWELSEG Demo of vowel segregation based on oscillators. 
% Guy Brown, 1998
% updated July 1999 for v2.1 by Martin

if nargin<1
  action='init';
end

switch action

case 'init'
  f=findobj('Tag','vowelSeg_fig');
  if ~isempty(f)
    figure(f);
  else  	
    vowelSeg_gui;
    set(gcf,'backingstore','off');
    hold on;
    ud.minChannel=1;
    ud.maxChannel=64;
    ud.minDelay=1;
    ud.maxDelay=126;
    ud.minOsc=1;
    ud.maxOsc=100;
    ud.frame=50;
    ud.correlogram=readCorrelogram('zero.acg');
    ud.oscillators=readOscillator('zero.osc');
    ud.oscplot=0;
    set(findobj('Tag','TimeSlider'),'Max',ud.maxOsc);
    set(findobj('Tag','TimeSlider'),'Min',ud.minOsc);
    set(findobj('Tag','TimeSlider'),'Value',ud.frame);
    
    % set up timbre regions for matching
    
    ud.ar_timbre=readTimbre('ar.timbre');
    ud.er_timbre=readTimbre('er.timbre');
    ud.ee_timbre=readTimbre('ee.timbre');
    ud.oo_timbre=readTimbre('oo.timbre');
    ud.or_timbre=readTimbre('or.timbre');
    
    ud.oscaxis=findobj('Tag','oscAxis');
    set(gca,'NextPlot','add','Drawmode','fast');
    
    ud.acgaxis=findobj('Tag','acgAxis');
    set(gca,'NextPlot','add','Drawmode','fast');
    
    ud.sumaxis=findobj('Tag','SummaryAxis');
    axes(ud.sumaxis);
    axis([ud.minDelay ud.maxDelay -5 30]);
    set(gca,'NextPlot','replacechildren','Drawmode','fast');
    axis manual;
    ud.sumplot=plot(0,0,'EraseMode','background');
    
    set(gcf,'UserData',ud); 
    
    plotOscillator;
    plotCorrelogram;
    vowelSeg('sliderMoved');   
  end

case 'sliderMoved'
  ud=get(gcf,'UserData');
  axes(findobj('Tag','oscAxis'));
  ud.frame=round(get(findobj('Tag','TimeSlider'),'Value'));
  set(findobj('Tag','TimeBox'),'String',num2str(ud.frame));
  set(gcf,'UserData',ud);
  set(ud.cursor,'XData',[ud.frame ud.frame]);
  set(gcf,'UserData',ud);
  plotCorrelogram;
  
case 'boxChanged'
  ud=get(gcf,'UserData');
  ud.frame=round(str2num(get(findobj('Tag','TimeBox'),'String')));
  ud.frame=max(min(ud.frame,ud.maxDelay),ud.minDelay);
  set(findobj('Tag','TimeSlider'),'Value',ud.frame);
  set(findobj('Tag','TimeBox'),'String',num2str(ud.frame));
  set(gcf,'UserData',ud);
  plotCorrelogram;
  
case 'zero'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('zero.osc');
  ud.correlogram=readCorrelogram('zero.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
case 'quarter'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('quarter.osc');
  ud.correlogram=readCorrelogram('quarter.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
case 'half'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('half.osc');
  ud.correlogram=readCorrelogram('half.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
case 'one'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('one.osc');
  ud.correlogram=readCorrelogram('one.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
case 'two'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('two.osc');
  ud.correlogram=readCorrelogram('two.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
case 'four'
  ud=get(gcf,'UserData');
  ud.oscillators=readOscillator('four.osc');
  ud.correlogram=readCorrelogram('four.acg');
  set(gcf,'UserData',ud);
  plotOscillator;
  plotCorrelogram;
  
otherwise
  maduievent('vowelSeg',action);
  
  
end

% -------------------------------------------------------------
% plot the oscillator display
% -------------------------------------------------------------

function plotOscillator()
ud=get(gcf,'UserData');
axes(findobj('Tag','oscAxis'));
cla; 
for chan=1:ud.maxChannel,
  plot(chan+2*(ud.oscillators(chan,:)-0.5));
end
ud.cursor=line([ud.frame ud.frame],[ud.minChannel ud.maxChannel],'EraseMode','xor');
set(gcf,'UserData',ud);

% -------------------------------------------------------------
% plot the correlogram display
% -------------------------------------------------------------

function plotCorrelogram()
ud=get(gcf,'UserData');
set(gcf,'CurrentAxes',ud.acgaxis);
cla;
idx=find(ud.oscillators(:,ud.frame)>0.5);
for chan=idx',
  plot(chan+5*(ud.correlogram(chan,:)-0.5));
end
s=sum(ud.correlogram(idx,:));
t=s(1:40);
set(gcf,'CurrentAxes',ud.sumaxis);
set(ud.sumplot,'XData',[5:130]);
set(ud.sumplot,'YData',s);
% display the string of rank order vowel matches
if (sum(idx)==0)
	set(findobj('Tag','scoreText'),'String','No vowel matches');
else
	score=zeros(5,2);
	score(:,1)=[1:5]';
	score(1,2)=match(t,ud.ar_timbre);
	score(2,2)=match(t,ud.er_timbre);
	score(3,2)=match(t,ud.ee_timbre);
	score(4,2)=match(t,ud.or_timbre);
	score(5,2)=match(t,ud.oo_timbre);
	score=sortrows(score,2);
	str=['Vowel matches in rank order: ' num2vow(score(5,1)) num2vow(score(4,1)) ...
	num2vow(score(3,1)) num2vow(score(2,1))  num2vow(score(1,1)) ];
	set(findobj('Tag','scoreText'),'String',str);
end

function s = num2vow(n)
switch(n)
case 1, s='AR ';
case 2, s='ER ';
case 3, s='EE ';
case 4, s='OR ';
case 5, s='OO ';
end

% -------------------------------------------------------------
% match the timbre region against a template
% -------------------------------------------------------------

function s=match(t,m)
% normalise
if (sum(t)==0)
  s=0.0;
else
  t=(t-mean(t))/std(t);
  s=1/(1+sum((t-m).^2));
end

% -------------------------------------------------------------
% read a correlogram from file
% -------------------------------------------------------------

function m=readCorrelogram(s)
fid=fopen(fullfile(madroot,'data','vowel_acgs',s),'r');
m=fread(fid,[64,126],'float');
fclose(fid);

% -------------------------------------------------------------
% read an oscillator array from file
% -------------------------------------------------------------

function m=readOscillator(s)
fid=fopen(fullfile(madroot,'data','vowel_acgs',s),'r');
m=fread(fid,[64,100],'float');
fclose(fid);

% -------------------------------------------------------------
% read a timbre template
% -------------------------------------------------------------

function t=readTimbre(s)
fid=fopen(fullfile(madroot,'data','vowel_acgs',s),'r');
t=fread(fid,[1,40],'float');
fclose(fid);
