www.gusucode.com > 声音的处理有:LPC,FFT,共振峰,频谱源码程序 > siganlandsystemusingMatlab/SSUM/spectrum/fourier/fourierexpofn.m

    function fourierexpofn(action,datastruct)
    if nargin < 1
        action='init';
    end

	% windowsize 64 doesn't work for 44100
	% Load sound, play, load diff sound, change window size, no work
	% clean up freq labels for log freq and linear freq

	name = mfilename;
	figname = [name(1:end-2) '_fig'];
	f=findobj('Tag',figname);
    handles = get(f,'UserData');

    switch action
		case 'help'
			display_help(figname);
        case 'init'
            setdefaults;
			reset(handles.specplot);
			reset(handles.timeplot);
		case 'loadsound'
            handles.audiodata = load_audiodata;
			if ~isfield(handles.audiodata, 'filenamepath')
                return;
            end
			if (size(handles.audiodata.data,2) > 1)
				handles.audiodata.data = to_mono(handles.audiodata.data);
			end
			handles = makeTimePlot(handles);
			handles = makeSpecPlot(handles);
			place_header(f, handles);
			set(handles.freqzoom,'Value',1);
			set(handles.ampzoom,'Value',0.5);
		case 'readinput'
			handles.audiodata = datastruct;
            clear datastruct;
			handles.audiodata.filenamepath = '';
			handles.audiodata.nBits = 16;
			handles.audiodata.channels = size(handles.audiodata.data,2);
            if handles.audiodata.channels > 1
                handles.audiodata.data = to_mono(handles.audiodata.data);
            end
			handles = makeTimePlot(handles);
			handles = makeSpecPlot(handles);
			place_header(f, handles);
			set(handles.freqzoom,'Value',1);
		case 'playsound'
			if isfield(handles, 'audiodata')
				audiodata = handles.audiodata;
				if (max(abs(audiodata.data)) > 1.0)
					audiodata.data = normalize(audiodata.data);
				end
				play_audiodata(audiodata, handles.play);
            end
        case 'zeropad'
            if isfield(handles, 'audiodata')
                handles = makeSpecPlot(handles);
            end
		case 'logfreq'
			if (get(handles.logfreq,'Value'))
				set(handles.specplot,'XScale','log');
			else
				set(handles.specplot,'XScale','linear');
			end
		case {'db'}
			if isfield(handles, 'audiodata')
				updateSpecPlot(handles);
				if (get(handles.dB,'Value'))
					axes(handles.specplot)
					ylabel('Log Magnitude (dB)');
				else
					axes(handles.specplot)
					ylabel('Amplitude');
				end
				fourierexpofn 'freqzoom';
				fourierexpofn 'ampzoom';
			end
		case 'entire'
			if isfield(handles, 'audiodata')
				handles = makeSpecPlot(handles);
				fourierexpofn 'freqzoom';
				fourierexpofn 'ampzoom';
			end
		case 'stem'
			if isfield(handles, 'audiodata')
				handles = makeSpecPlot(handles);
				fourierexpofn 'freqzoom';
				fourierexpofn 'ampzoom';
			end
		case {'fftsize','window','smoothfft'}
			if isfield(handles, 'audiodata')
				contents = get(handles.fftsize,'String');
				fftsize = contents{get(handles.fftsize,'Value')};
				if strncmp(fftsize,'Entire',6)
					fftsize = length(handles.audiodata.data);
				else
					fftsize = str2num(fftsize);
				end
				wintime = fftsize/handles.audiodata.Fs;
				handles.right = handles.left + wintime;
                if handles.right > handles.maxtime
                    handles.right = handles.maxtime;
                    handles.left = handles.maxtime - wintime;
                end
                set(handles.l,'XData',[handles.left handles.left]);
				set(handles.r,'XData',[handles.right handles.right]);
				handles = makeSpecPlot(handles);
				fourierexpofn 'freqzoom';
				fourierexpofn 'ampzoom';
			end
		case 'normalize'
            if isfield(handles,'audiodata')
                handles.audiodata.data = normalize(handles.audiodata.data);
                handles = makeTimePlot(handles);
                handles = makeSpecPlot(handles);
            end
		% The following taken in large part from MAD.
		case 'left'
			set(gcf,'WindowButtonMotionFcn','fourierexpofn moveleft');
			set(gcf,'WindowButtonUpFcn','fourierexpofn release');
		case 'right'
			set(gcf,'WindowButtonMotionFcn','fourierexpofn moveright');
			set(gcf,'WindowButtonUpFcn','fourierexpofn release');
		case 'moveleft'
			handles = moveleft(handles);
			updateSpecPlot(handles);
		case 'moveright'
			handles = moveright(handles);
			updateSpecPlot(handles);
		case 'release'
			set(gcf,'WindowButtonMotionFcn','');
			set(gcf,'WindowButtonUpFcn','');
        case {'sonogram', 'alias'}
            if isfield(handles,'audiodata'),
                audiodata = handles.audiodata;
			    switch action
					case 'sonogram'
				    	sonoexpogui(audiodata);
					case 'alias'
                    	aliasexpogui(audiodata);
			    end
            end
		case 'freqzoom'
            if isfield(handles,'audiodata')
                val = get(handles.freqzoom,'Value');
                if val == 0,
                    val = 0.001;
                end
                Fs = handles.audiodata.Fs;
				if get(handles.entire,'Value')
                	set(handles.specplot,'XLim',[-val*Fs/2 val*Fs/2])
				else
                	set(handles.specplot,'XLim',[0 val*Fs/2])
				end
            end
        case 'ampzoom'
            if isfield(handles,'audiodata')
                val = get(handles.ampzoom,'Value');
                if val == 0,
                    val = 0.001;
                end
                if get(handles.dB,'Value'),
                    set(handles.specplot,'YLim',[-100 (2*val*100-40)])
                else
                    set(handles.specplot,'YLim',[0 val*200])
                end
            end
		case 'print'
			print_figure(f);
		case 'close'
			close_figure(f,figname(1:end-4));
			return;

	end
	set(f,'UserData',handles);

% --------------------------------------------------------------------
function handles = makeTimePlot(handles);
	contents = get(handles.fftsize,'String');
	fftsize = contents{get(handles.fftsize,'Value')};
	if strncmp(fftsize,'Entire',6)
		fftsize = length(handles.audiodata.data);
	else
		fftsize = str2num(fftsize);
	end

	axes(handles.timeplot);
	cla;
	handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/...
			handles.audiodata.Fs];
	maxtime = length(handles.t)/handles.audiodata.Fs;
    handles.maxtime = maxtime;
	handles.winleft = 0;
	handles.winright = maxtime;
	plot(handles.t,handles.audiodata.data)
	xlabel('time (s)');
	set(handles.timeplot,'NextPlot','replacechildren','Drawmode','fast',...
			'XLim',[0 maxtime], 'YLim', [-1.1 1.1]);
	grid;
	hold on;
    handles.left = 0.1*maxtime;
    handles.delta = fftsize/handles.audiodata.Fs;
    handles.right = handles.left + handles.delta;
    handles.l=line([handles.left handles.left],get(gca,'YLim'),'Color','r',...
		'ButtonDownFcn','fourierexpofn left','LineWidth', 2,'EraseMode','xor');
    handles.r=line([handles.right handles.right],get(gca,'YLim'),'Color','r',...
		'ButtonDownFcn','fourierexpofn right','LineWidth', 2,'EraseMode','xor');
	handles.step=0.2*maxtime;
 
function handles = makeSpecPlot(handles);
	contents = get(handles.fftsize,'String');
	fftsize = contents{get(handles.fftsize,'Value')};
	if strncmp(fftsize,'Entire',6)
		fftsize = length(handles.audiodata.data);
	else
		fftsize = str2num(fftsize);
	end
	contents = get(handles.Window,'String');
	shape = contents{get(handles.Window,'Value')};

    zpfactor = str2num(get(handles.zpfactor,'String'))+1;
    
	axes(handles.specplot);
	% Get x-position of samples
	startpos = floor(handles.left*handles.audiodata.Fs+1);
	signal = handles.audiodata.data(startpos:startpos+fftsize-1).*...
			get_windowdata(fftsize, shape);
	f = fftshift(fft(signal,fftsize*zpfactor));
	if (get(handles.dB,'Value'))
		f = 20*log10(1e-10+abs(f));
	else
		f = abs(f);
	end
	freqs = linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,fftsize*zpfactor);

	if (get(handles.smoothfft,'Value'))
		f=interp1(linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2, ...
			length(f)),f,freqs);
	end

	if get(handles.stem,'Value')
		handles.sp = stem(freqs,f);
	else
		handles.sp = plot(freqs,f);
	end

	if get(handles.entire,'Value')
		set(handles.specplot, ...
			'XLim',[-handles.audiodata.Fs/2 handles.audiodata.Fs/2], ...
			'YLim',[-100 60]);
	else
		set(handles.specplot,'XLim',[0 handles.audiodata.Fs/2], ...
			'YLim',[-100 60]);
	end

	if (get(handles.logfreq,'Value'))
		set(handles.specplot,'XScale','log');
	else
		set(handles.specplot,'XScale','linear');
	end
	axis xy; grid;
	xlabel('Frequency (kHz)');
	ylabel('Log Magnitude (dB)');
	set(handles.sp, 'EraseMode','background','LineWidth',1);


% --------------------------------------------------------------------
function updateTimePlot(handles)
	axes(handles.timeplot)
	plot(handles.t,handles.audiodata)
	xlabel('time (s)');
	grid;

function updateSpecPlot(handles)
	contents = get(handles.fftsize,'String');
	fftsize = contents{get(handles.fftsize,'Value')};
	if strncmp(fftsize,'Entire',6)
		fftsize = length(handles.audiodata.data);
	else
		fftsize = str2num(fftsize);
	end
	contents = get(handles.Window,'String');
	shape = contents{get(handles.Window,'Value')};
	% Get x-position of samples
	startpos = floor(handles.left*handles.audiodata.Fs+1);
	signal = handles.audiodata.data(startpos:startpos+fftsize-1).*...
			get_windowdata(fftsize, shape);
    zpfactor = str2num(get(handles.zpfactor,'String'))+1;
        
	f = fftshift(fft(signal,fftsize*zpfactor));
	if (get(handles.dB,'Value'))
		f = 20*log10(1e-10+abs(f));
	else
		f = abs(f);
	end
	freqs = linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,fftsize*zpfactor);

	if (get(handles.smoothfft,'Value'))
		f=interp1(linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,length(f)),f,freqs);
	end
	if (get(handles.logfreq,'Value'))
		set(handles.specplot,'XScale','log');
	else
		set(handles.specplot,'XScale','linear');
	end

	if get(handles.stem,'Value')
		set(handles.sp(1),'YData',f);
		temp = get(handles.sp(2),'YData');
		temp(2:3:end) = f;
		set(handles.sp(2),'YData',temp);
	else
		set(handles.sp, 'YData', f);
	end


% --------------------------------------------------------------------
function ud = moveleft(ud)
	contents = get(ud.fftsize,'String');
	fftsize = contents{get(ud.fftsize,'Value')};
	if strncmp(fftsize,'Entire',6)
		fftsize = length(ud.audiodata.data);
	else
		fftsize = str2num(fftsize);
	end
	currentPoint=get(gca,'CurrentPoint');
	ud.left=currentPoint(1);
	wintime = fftsize/ud.audiodata.Fs;

	if ud.left <= ud.winleft
		ud.left=0;
	end
	if ud.left >= (ud.winright-wintime)
		ud.left=ud.winright-wintime;
	end

	set(ud.l,'XData',[ud.left ud.left]);
	set(ud.r,'XData',[ud.left+wintime ud.left+wintime]);

function ud = moveright(ud)
	contents = get(ud.fftsize,'String');
	fftsize = contents{get(ud.fftsize,'Value')};
	if strncmp(fftsize,'Entire',6)
		fftsize = length(ud.audiodata.data);
	else
		fftsize = str2num(fftsize);
	end
	currentPoint=get(gca,'CurrentPoint');
	ud.right=currentPoint(1);
	wintime = fftsize/ud.audiodata.Fs;

	if ud.right <= (ud.winleft+wintime)
		ud.right=wintime;
	end
	if ud.right >= (ud.winright)
		ud.right=ud.winright;
	end
	ud.left = ud.right - wintime;

	set(ud.r,'XData',[ud.right ud.right]);
	set(ud.l,'XData',[ud.right-wintime ud.right-wintime]);