function rs = ispect_speech(instruct, outfile)

% iSPECT_SPEECH  Interactive version of the namesake script which 
% demonstrates the effects of window length and overlap on the spectral
% analysis of a speech signal.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Set constants
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global siglen fixedfftlen;
siglen = 2000;
fixedfftlen = 2048;
Fs = 10000; 
samplen = 1024; % Length for the vowel segment

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 1	Initialize the return string
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

rs = char('');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 2	Set directory for storage of graphic files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Change working dir to temp dir on ACS machine
% NOTE: We won't make use of the Matweb variable MLDIR
tempdir = '/var/local/httpd/htdocs/matweb/tmp';

% Uncomment below when running script from a stand-alone test file
%tempdir = '/afs/athena.mit.edu/course/6/6.555/matweb/tmp';
cd(tempdir);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 3	Get HTML form input variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% Get unique identifier (to form file name)
mlid = getfield(instruct, 'mlid');

% Show previous plot?
try
  compareplot = getfield(instruct, 'compareplot');
catch
  compareplot = ' no';
end

% Show time signal? Field non-existent if box unchecked
try
   showtime = getfield(instruct, 'showtime');
catch
   showtime = ' no';
end

% Display magnitude in dB?
try
   showdB = getfield(instruct, 'showdB');
catch
   showdB = ' no';
end

% Use Welch's method?
try
  welch = getfield(instruct, 'welch');
catch
  welch = ' no';
end


% Get upper frequency limit for display
upperflim = str2double(getfield(instruct, 'upperflim'));


% Get current plot's color
% $$$ ccolor = lower(getfield(instruct, 'ccolor'));

% Get saved plot's color
% $$$ scolor = lower(getfield(instruct, 'scolor'));

% Get standard parameters
[speechdir,speechdat,speechsamp,winlen,wintype,fftlen,overlap] = ...
    getParams(instruct);


% Get saved parameters
if (strcmp(compareplot,'true'))
   [sspeechdat,sspeechsamp,swinlen,swintype,sfftlen,soverlap] = ...
       getSaved(instruct);
   
   
% $$$    % Create plot title for debugging purpose
% $$$ %   stitle = sprintf('Saved values: A0=%.2f, A1=%.2f, f0=%.2f, f1=%.2f, winlen=%d, wintype=%s, fftlen=%d', sA0, sA1, sf0, sf1, swinlen, swintype, sfftlen); 
% $$$ 
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 4	Perform MATLAB computations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Load signal using s = load('file.mat'), the content of the
% MAT file is placed in the structure s, with the field names
% of s corresponding to the names of the retrieved variables.
eval(sprintf('s = load(''%s/%s'');', speechdir, speechdat));   

% Select the sample to be examined
try
  eval(sprintf('sampbegin = s.%s;', speechsamp));
catch
  sampbegin = s.start;
end

signal = s.source;
sampend = min((sampbegin + samplen - 1),length(signal));
signal = signal(sampbegin:sampend);
siglen = length(signal);



[w,v,W,Vf,Vk] = compFFT(signal, winlen, wintype, fftlen);
if (strcmp(showdB, 'true'))
  W = 20*log10(W);
  Vf = 20*log10(Vf);
  Vk = 20*log10(Vk);
end

if (strcmp(welch,'true'))
  [P, F] = compSpectrum(signal,winlen,wintype,fftlen,overlap,Fs);
  if (strcmp(showdB,'true'))
    P = 10*log10(P);
  end
end

if (strcmp(compareplot, 'true'))
  eval(sprintf('s = load(''%s/%s'');', speechdir, sspeechdat));   
  
  % Select the sample to be examined
  try
    eval(sprintf('ssampbegin = s.%s;', sspeechsamp));
  catch
    ssampbegin = s.start;
  end
  ssignal = s.source;
  sampend = ssampbegin + samplen - 1;
  ssignal = ssignal(ssampbegin:sampend);
  ssiglen = length(ssignal);

  [sw,sv,sW,sVf,sVk] = compFFT(ssignal, swinlen, swintype, sfftlen);
  if (strcmp(showdB, 'true'))
    sW = 20*log10(sW);
    sVf = 20*log10(sVf);
    sVk = 20*log10(sVk);
  end
  
    if (strcmp(welch,'true'))
    [sP, sF] = ...
	compSpectrum(ssignal,swinlen,swintype,sfftlen,soverlap,Fs);
    if (strcmp(showdB,'true'))
      sP = 10*log10(sP);
    end
  end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Generate graphics
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Specify colors, shapes for current and saved plots
ccolor = 'r';
ccolorshape = [ccolor 'o'];
scolor = 'b';
scolorshape = [scolor 'd'];


% Specify time axes
upperxlim = floor(winlen/2);    % upper limit of window
if (mod(winlen,2) == 1)		% if window length is odd
   lowerxlim = -upperxlim;	% lower limit of window
else
   lowerxlim = -(upperxlim-1);
end

% axis for time windows
% window
axt1 = [lowerxlim-1 upperxlim+1 0 max(w)+0.2*abs(max(w))];
% windowed signal
axt2 = [lowerxlim-1 upperxlim-1 min(v)-0.2*abs(min(v)) ...
      max(v)+0.2*abs(max(v))];

% axis for frequency windows

% frequency vectors
fixedincr = 1./(fixedfftlen);
fixedf = Fs*[0:fixedincr:1-fixedincr];

incr = 1./(fftlen);
f = Fs*[0:incr:1-incr];



  


if (strcmp(compareplot,'true'))
  sincr = 1./(fftlen);
  sf = Fs*[0:sincr:1-sincr];
  axf1 = [0 upperflim 0 1.1*max([max(W) max(sW) ])];
  axf2 = [0 upperflim 0 1.1*max([ max(Vf) max(sVf) ])];
  if (strcmp(welch,'true'))
    axf3 = [0 upperflim 0 1.1*max([ max(P) max(sP) ])];
  end
else
   axf1 = [0 upperflim 0 1.1*max(W)];
   axf2 = [0 upperflim 0 1.1*max(Vf)];
   if (strcmp(welch,'true'))
     axf3 = [0 upperflim 0 1.1*max(P)];
   end
end


% Cleanup old jpegs
wscleanup('ml*spect_speech.jpeg',1); % Delete jpegs older than 1
                                     % hour

% Create "invisible" figure	
fhandle = figure('Visible','off');
clf reset;
cla reset;
% Adjust the size and position of the JPEG image
set(fhandle, 'PaperPosition', [0 0 8 6])

% Plot
winindex = 1;
ncolumns = 1;
nrows = 3;
if (strcmp(showtime, 'true'))
  ncolumns = 2;
  subplot(nrows, ncolumns, winindex);
  
  % Plot w[n]
  coolplot([lowerxlim:upperxlim],w(1:winlen),ccolorshape);
  axis(axt1)
  ylabel('w[n]');
  winindex = winindex + 1;
  
  % Plot |W(f)|
  subplot(nrows, ncolumns, winindex);
  curlegend = plot(fixedf,W,ccolor);
  if (strcmp(compareplot,'true'))
    hold on;
    slegend = plot(fixedf,sW,scolor);
    hold off;
  end
  axis(axf1);
  set(gca,'YAxisLocation','right')
  if (strcmp(showdB, 'true'))
    ylabel('|W(f)| (dB)');
  else
    ylabel('|W(f)|');
  end
  winindex = winindex + 1;

  %Plot v[n]
  subplot(nrows, ncolumns, winindex);
  coolplot([lowerxlim:upperxlim], v(1:winlen), ccolorshape);
  axis(axt2);
  ylabel('v[n]');
  winindex = winindex + 1;

  % Plot |V(f)|
  subplot(nrows, ncolumns, winindex);
  plot(fixedf,Vf,ccolor);
  if (strcmp(compareplot,'true'))
    hold on;
    plot(fixedf,sVf,scolor);
    hold off;
  end
  axis(axf2);
  set(gca,'YAxisLocation','right')
  if (strcmp(showdB, 'true'))
    ylabel('|V(f)| (dB)')
  else
    ylabel('|V(f)|')
  end
  winindex = winindex + 1;

  % Empty plot window
  % Still need to show axis info
  subplot(nrows, ncolumns, winindex);
  ah = gca;       % get handle so we can put a legend on this axis
  axis(axt2);	   % but show labels
  xlabel('n')
  set(ah, 'TickDir', 'out')       % tick direction is outward
  set(ah, 'YTickLabel', '', 'YTick', [])      % kill y-axis
  set(ah, 'Box', 'on')			       % turn on box
  hold on;
  winindex = winindex + 1;

  % |V[k]| or |P[k]|
  subplot(nrows, ncolumns, winindex);
  if (strcmp(welch,'true'))
    if (strcmp(compareplot,'true'))
      coolplot(sF,sP,scolorshape);
      hold on;
    end
    coolplot(F,P,ccolorshape);
    ylab = '|P[k]|';
    axis(axf3);
  else
    if (strcmp(compareplot,'true'))
      coolplot(sf,sVk,scolorshape);
      hold on;
    end
    coolplot(f,Vk,ccolorshape);
    ylab = '|V[k]|';
    axis(axf2);
  end

  set(gca,'YAxisLocation','right');
  xlabel('Frequency (Hz)')
  if (strcmp(showdB,'true'))
    ylab = [ylab ' (dB)'];
  end
  ylabel(ylab);

else
  
  % Plot |W(f)|
  subplot(nrows, ncolumns, winindex);
  ah = gca; % Get handle so we can put a legend on this axis
  if (strcmp(compareplot,'true'))
    slegend = plot(fixedf,sW,scolor);
    hold on;
  end
  curlegend = plot(fixedf,W,ccolor);
  axis(axf1);
  set(gca,'YAxisLocation','right')
  if (strcmp(showdB, 'true'))
    ylabel('|W(f)| (dB)');
  else
    ylabel('|W(f)|');
  end
  winindex = winindex + 1;

  % Plot |V(f)|
  subplot(nrows, ncolumns, winindex);
  if (strcmp(compareplot,'true'))
    plot(fixedf,sVf,scolor);
    hold on;
  end
  plot(fixedf,Vf,ccolor);
  axis(axf2);
  set(gca,'YAxisLocation','right')
  if (strcmp(showdB, 'true'))
    ylabel('|V(f)| (dB)')
  else
    ylabel('|V(f)|')
  end
  winindex = winindex + 1;

  % |V[k]| or |P[k]|
  subplot(nrows, ncolumns, winindex);
  if (strcmp(welch,'true'))
    if (strcmp(compareplot,'true'))
      coolplot(sF,sP,scolorshape);
      hold on;
    end
    coolplot(F,P,ccolorshape);
    ylab = '|P[k]|';
    axis(axf3);
  else
    if (strcmp(compareplot,'true'))
      coolplot(sf,sVk,scolorshape);
      hold on;
    end
    coolplot(f,Vk,ccolorshape);
    ylab = '|V[k]|';
    axis(axf2);
  end

  set(gca,'YAxisLocation','right');
  xlabel('Frequency (Hz)')
  if (strcmp(showdB,'true'))
    ylab = [ylab ' (dB)'];
  end
  ylabel(ylab);


end


subplotmx(nrows,ncolumns);  %compress the subplots

% Create legend.  Must be _after_ compressing subplots as 
% plots with legend are not affected by subplotmx   
if (strcmp(compareplot,'true'))
  lh = legend(ah, [curlegend slegend], 'Current', 'Saved',0); 
  % The following if statement should not be needed, it was
  % necessary to add it after the version of Matlab running on the
  % server changed.  I believe this is a Matlab bug, and will
  % hopefully resolve in the future.  Right now, this prevents
  % Matlab from automatically placing the legend box to avoid
  % conflicts.
  if (strcmp(showtime, 'true'))
    set(lh,'Position',[0.25 0.22 0.13 0.06])  
  else
    set(lh,'Position',[0.75 0.8 0.13 0.06])
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 5	Put output variables in an output structure
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Render jpeg and write to file.
drawnow;
s.GraphFileName = sprintf('%sspect_speech.jpeg', mlid);
wsprintjpeg(fhandle, s.GraphFileName);

close all hidden;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STAGE 6	Call HTMLREP with output struct and output HTML
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Put name of graphic file into HTML template file.
templatefile = ...
    '/afs/athena/course/6/6.555/matweb/samp/ispect2_speech.html';

if (nargin == 1)
  rs = htmlrep(s, templatefile);
elseif (nargin == 2)
  disp('Running stand alone tester');
  rs = htmlrep(s, templatefile, outfile);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Subfunctions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% getSaved(instruct) gets the values of saved variables from 
% the input structure.  Saved variable names begin with 's'.
function [sspeechdat,sspeechsamp,swinlen,swintype,sfftlen,soverlap] ...
    = getSaved(instruct)

   % Get name of SPEECH file
   sspeechdat = getfield(instruct, 'sspeechdat');
   sspeechsamp = getfield(instruct, 'sspeechsamp');
   
   % Get window length
   swinlen = str2double(getfield(instruct, 'swinlen'));
   % Get window type
   swintype = lower(getfield(instruct, 'swintype'));

   % Get FFT length
   sfftlen = str2double(getfield(instruct, 'sfftlen'));

   % Get overlap
   soverlap = str2double(getfield(instruct,'soverlap'));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% getParams(instruct) gets the values of standard variables from 
% the input structure
function [speechdir,speechdat,speechsamp,winlen,wintype,fftlen,overlap] ...
    = getParams(instruct)

   % Get name of SPEECH file
   speechdir = getfield(instruct, 'speechdir');
   speechdat = getfield(instruct, 'speechdat');
   speechsamp = getfield(instruct, 'speechsamp');
   
   % Get window length
   winlen = str2double(getfield(instruct, 'winlen'));
   % Get window type
   wintype = lower(getfield(instruct, 'wintype'));

   % Get FFT length
   fftlen = str2double(getfield(instruct, 'fftlen'));

   % Get overlap
   overlap = str2double(getfield(instruct,'overlap'));












