function [f,spect]=dataspect(y,fs)
% DATASPECT  real data spectrum demo.  Use the graphic interface
% to load a data file.
% DATASPECT(Y,FS) displays your data (array Y at sampling 
% frequency FS) and its spectrum.  Push the Return button to return 
% arrays of frequency axis and spectrum to the root workspace.

if  (nargin==1 & isstr(y))	% callbacks 
	action=y;
	d=get(gcbf,'UserData');
	switch (action)
	case 'SND'
		[fname,pname]=uigetfile('*','Select Sound File');
		if (fname)
			cd(pname)
         eval('[data,d.fs]=readsnd(fname);')
         d.y=data(:)';
			d.title=['Data from file ',fname];
			set(d.fstxt,'String',['fs = ',num2str(d.fs)])
			d=drawspect(d);
		end
	case 'WAV'
		[fname,pname]=uigetfile('*.wav','Select WAV File');
		if (fname)
			cd(pname)
         [data,d.fs]=wavread(fname);
         d.y=data(:)';
			d.title=['Data from file ',fname];
			set(d.fstxt,'String',['fs = ',num2str(d.fs)])
			d=drawspect(d);
		end
	case 'TXT'
		[fnamext,pname]=uigetfile('*.txt','Select TXT File');
		if (fnamext)
			fname=strtok(fnamext,'.');
			if ~isletter(fname(1))	fname=['X',fname];	end
			cd(pname)
			load(fnamext,'-ASCII')
			eval(['ydatBR549=',fname,'(:)'';'])
			clear(fname)				% just in case the file name 
			d=get(gcbf,'UserData');		% was "d.txt"  !
			d.y=ydatBR549;
			fs=inputdlg('Enter Sampling Frequency','fs',1,{num2str(d.fs)});
			if length(fs)	d.fs=str2num(fs{1});	end
			d.title=['Data from file ',fnamext];
			set(d.fstxt,'String',['fs = ',num2str(d.fs)])
			d=drawspect(d);
		end
	case 'var'	% load main workspace variable 
		whostr=evalin('base','who');
		idx=listdlg('ListString',whostr,'SelectionMode','single', ...
			'ListSize',[200 200],'Name','Select Variable',...
			'PromptString','Main Workspace Variables');
		if (idx)
			data=evalin('base',whostr{idx});
			d.y=data(:)';
			fs=inputdlg('Enter Sampling Frequency','fs',1,{num2str(d.fs)});
			if length(fs)	d.fs=str2num(fs{1});	end
			d.title=['Data from variable ',whostr{idx}];
			set(d.fstxt,'String',['fs = ',num2str(d.fs)])
			d=drawspect(d);
		end
	case 'play'
		sound(d.y,d.fs)
	case 'zoom'
		if (get(gcbo,'Value'))
			axes(d.datax),		zoom on
			axes(d.spectax),	zoom on
		else
			axes(d.datax),		zoom out,	zoom off,	axis auto
			axes(d.spectax),	zoom out,	zoom off,	axis auto
		end
	case 'popwin'
		d.winnum=get(gcbo,'Value');
		d=drawspect(d);
	case 'popspect'
		d.spectmode=get(gcbo,'Value');
		d=drawspect(d);
	case 'rbutton'
		assignin('base','freq',d.freq)
		N=length(d.y);
		switch d.spectmode
		case 1
			assignin('base','AY',2*abs(d.Y)/N)
			disp('Returned Amplitude spectrum to [freq,AY]')
		case 2
			assignin('base','PY',2*d.Y.*conj(d.Y)/N^2)
			disp('Returned Power spectrum to [freq,PY]')
		case 3
			assignin('base','CY',2*d.Y/N)
			disp('Returned Complex spectrum to [freq,CY]')
		case 4
			power=2*d.Y.*conj(d.Y)/N^2;
			assignin('base','dB',10*log10(power))
			disp('Returned Decibel spectrum to [freq,dB]')
		end
	case 'd'
		f=d;
	case 'help'
    	helpwin('aboutdataspect')
	otherwise
		disp(['callback ',action,' unknown'])
	end
	set(gcbf,'UserData',d)
	
elseif (nargin==0 | (nargin==2 & isnumeric(y)))	% start-up
	if (nargin==0)
		y=[0 1];
		fs=1;
		datatitle='no data';
	else
		y=y(:)';
		datatitle='Your Data';
	end		
	d=struct('y',y, ...
		'fs',fs, ...
		'winnum',1, ...
		'title',datatitle, ...
		'spectmode',1, ...
		'freq',zeros(10,1), ...
		'Y',zeros(10,1), ...
		'datax',0,'spectax',0,'fstxt',0);
    a=figure('Units','normalized','Position',[0.2 0.1 0.75 0.8], ...
      'Numbertitle','off','Name','DataSpect','Tag','DataSpectBR549');
	set(0,'ShowHiddenHandles','on')
	wh=findobj('Tag','DataSpectBR549');
	s=length(wh);
	if (s>1)
		set(a,'Name',['DataSpect #',num2str(s)]);
	end
	set(0,'ShowHiddenHandles','off')
	currdir=pwd;
	homedir=pathto('mainswitch.m');
	cd(homedir)
	dm=dir('fontpref.mat');
	if (length(dm))
		load fontpref
		set(a,'DefaultAxesFontName',axfont.FontName, ...
			'DefaultAxesFontUnits',axfont.FontUnits, ...
			'DefaultAxesFontSize',axfont.FontSize, ...
			'DefaultAxesFontWeight',axfont.FontWeight, ...
			'DefaultAxesFontAngle',axfont.FontAngle, ...
			'DefaultUicontrolFontName',uifont.FontName, ...
			'DefaultUicontrolFontUnits',uifont.FontUnits, ...
			'DefaultUicontrolFontSize',uifont.FontSize, ...
			'DefaultUicontrolFontWeight',uifont.FontWeight, ...
			'DefaultUicontrolFontAngle',uifont.FontAngle)
	end
	cd(currdir)
	color=get(a,'Color');
	d.datax=axes('Parent',a,'Units','normalized','XGrid','on', ...
		'YGrid','on','Position',[0.33 0.57 0.6 0.38]);
	d.spectax=axes('Parent',a,'Units','normalized','XGrid','on', ...
		'YGrid','on','Position',[0.33 0.07 0.6 0.38]);
	if strcmp(computer,'MAC2')
		c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
		   'Position',[0.015 0.902 0.15 0.048],'String','load Sound', ...
		   'callback','dataspect SND');
	end
	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
	   'Position',[0.015 0.854 0.15 0.048],'String','load WAV', ...
	   'callback','dataspect WAV');
	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
	   'Position',[0.015 0.806 0.15 0.048],'String','load TXT', ...
	   'callback','dataspect TXT');
	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
	   'Position',[0.015 0.758 0.15 0.048],'String','load variable', ...
	   'callback','dataspect var');
	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
	   'Position',[0.015 0.678 0.15 0.048],'String','play sound', ...
      'callback','dataspect play');
	d.fstxt=uicontrol('Parent',a,'Style','text','Units','normalized', ...
      'Position',[0.015 0.630 0.15 0.048],'BackgroundColor',color, ...
	  'String',['fs = ',num2str(d.fs)]);
	c=uicontrol('Parent',a,'Style','text','Units','normalized', ...
	   'Position',[0.015 0.548 0.195 0.048],'BackgroundColor',color, ...
	   'String','Apply Window');
	c=uicontrol('Parent',a,'Style','popupmenu','Units','normalized', ...
	   'Position',[0.015 0.5 0.195 0.048], ...
	   'String','None|Bartlett|Hanning|Hamming|Kaiser 2.5', ...
	   'Callback','dataspect popwin','Value',d.winnum);
	c=uicontrol('Parent',a,'Style','checkbox','Units','normalized', ...
		'Position',[0.015 0.402 0.195 0.048],'String','Zoom Control', ...
		'callback','dataspect zoom');
	c=uicontrol('Parent',a,'Style','text','Units','normalized', ...
	   'Position',[0.015 0.188 0.195 0.048],'BackgroundColor',color, ...
	   'String','Spectrum');
	c=uicontrol('Parent',a,'Style','popupmenu','Units','normalized', ...
	   'Position',[0.015 0.14 0.195 0.048], ...
	   'String','Amplitude|Power|Complex|Decibel', ...
	   'Callback','dataspect popspect','Value',d.spectmode);
	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
	   'Position',[0.015 0.015 0.15 0.05], ...
	   'String','Return','Callback','dataspect rbutton');
	b = uimenu('Parent',a,'Label','DataSpect');
	c1 = uimenu('Parent',b,'Label','Help','Enable','on','Tag','helpmenu', ...
		'Callback','dataspect help');
	c2 = uimenu('Parent',b,'Label','Visible','Enable','on','Tag','onmenu', ...
		'Callback',['set(gcf,''Handlevisibility'',''on'');', ...
			'set(get(gcbo,''UserData''),''Enable'',''on'');', ...
			'set(gcbo,''Enable'',''off'')']);
	c3 = uimenu('Parent',b,'Label','Callback','Enable','off', ...
		'Callback',['set(gcf,''Handlevisibility'',''callback'');', ...
			'set(get(gcbo,''UserData''),''Enable'',''on'');', ...
			'set(gcbo,''Enable'',''off'')'],'UserData',c2);
	set(c2,'UserData',c3)
% 	c=uicontrol('Parent',a,'Style','pushbutton','Units','normalized', ...
% 	   'Position',[0.18 0.07 0.05 0.06],'String','d', ...
% 	   'Callback','d=dataspect(''d'')');
	d=drawspect(d);
	set(a,'HandleVisibility','callback')
	set(a,'UserData',d)
	homedir=pathto('dataspect.m');
	p=path;
	if ~size(findstr(p,homedir))
		path(path,homedir)
		disp([homedir,'  added to search path'])
	end
else
	error('Argument Error!')
end

function d=drawspect(d)	% update displays
axes(d.datax),	cla
N=length(d.y);
t=[0:N-1]/d.fs;
switch (d.winnum)
case 1	% no window
	w=ones(1,N);
case 2	% Bartlett window
	w=2*[0:N/2]/N;
	if rem(N,2)	% odd length
		w=[w w((N+1)/2:-1:2)];
	else		% even length
		w=[w w(N/2:-1:2)];
	end
case 3	% Hanning window
	w=0.5*(1-cos(2*pi*(0:N-1)/N));
case 4	% Hamming window
	w=0.54-0.46*cos(2*pi*(0:N-1)/N);
case 5	% Kaiser window using alpha=2.5
	m=N/2;	t=[0:N-1];
	w=besseli(0,2.5*pi*sqrt(1-((t-m)/m).^2))/besseli(0,2.5*pi);
end
y=w.*d.y;		% apply window
plot(t,y,'x-'), grid on
xlabel('Time'),ylabel('data y(t)'),title(d.title)
half=floor(N/2);
d.freq=[0:half]/N*d.fs;
Y=fft(y);
d.Y=Y(1:half+1);
axes(d.spectax),	legend off,	cla
switch (d.spectmode)
case 1
	plot(d.freq,2*abs(d.Y)/N,'x-');
	xlabel('Frequency'),ylabel('A')
	title('Amplitude Spectrum')
case 2
	plot(d.freq,2*d.Y.*conj(d.Y)/N^2,'x-')
	xlabel('Frequency'),ylabel('P')
	title('Power Spectrum')
case 3
	plot(d.freq,2*real(d.Y)/N,'rx'), hold on
	plot(d.freq,2*imag(d.Y)/N,'bo')
	legend('real','imag')
	xlabel('Frequency'),ylabel('Y')
	title('Complex Spectrum')
case 4
	power=2*d.Y.*conj(d.Y)/N^2;
	plot(d.freq,10*log10(power),'x-');
	xlabel('Frequency'),ylabel('dB')
	title('Decibel Spectrum')
end
grid on

function dest=pathto(fname)
r=which(fname);
[tok1,r]=strtok(r,filesep);
dest=tok1;
[tok2,r]=strtok(r,filesep);
while ~isempty(r)
	tok1=tok2;
	dest=[dest,filesep,tok1];
	[tok2,r]=strtok(r,filesep);
end

% by Tim Conover 199
