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

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

	% Duration is wrong on titlebar
	% Include "loading" dialog

    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.timeplot);
			reset(handles.specplot);
		case 'loadsound'  
            handles.audiodata{1} = load_audiodata;
			if ~isfield(handles.audiodata{1}, 'filenamepath')
				return;
			end
			if (size(handles.audiodata{1}.data,2) > 1)
				handles.audiodata{1}.data = to_mono(handles.audiodata{1}.data);
			end
            handles = analyze(handles);

			contents = get(handles.fftsize,'String');
			fftsize = str2double(contents{get(handles.fftsize,'Value')});
			contents = get(handles.Window,'String');
			shape = contents{get(handles.Window,'Value')};
            [handles.spectrum{1}, handles.bin{1}, handles.st{1}] = ...
                        spectrogram(handles.audiodata{1}, fftsize, shape);
			[handles.spectrum{2}, handles.bin{2}, handles.st{2}] = ...
				spectrogram(handles.audiodata{2}, fftsize, shape);
			handles = makeTimePlot(handles);
			handles = makeSpecPlot(handles);
			linkedzoom([handles.timeplot, handles.specplot],'onx');
			headtext = [ handles.audiodata{1}.filenamepath '  Duration: ' ...
						 num2str(length(handles.audiodata{1}.data)/handles.audiodata{1}.Fs) ' s'...  
						'  Fs: ' num2str(handles.audiodata{1}.Fs) ' Hz'...
						'  Channels: ' num2str(handles.audiodata{1}.channels)...
						'  Bits: ' num2str(handles.audiodata{1}.nBits)];
            set(f, 'Name', headtext);
            set(handles.freqzoom,'Value',1.0);
		case 'readinput'
            % This will read in analysis data and load accompanying sound
            setdefaults;
			reset(handles.timeplot);
			reset(handles.specplot);
			audiodata = datastruct;
			clear datastruct;
			if (size(audiodata.data,2) > 1)
				audiodata.data = to_mono(audiodata.data);
			end
            handles.audiodata{1} = audiodata;
            handles = analyze(handles);

			contents = get(handles.fftsize,'String');
			fftsize = str2double(contents{get(handles.fftsize,'Value')});
			contents = get(handles.Window,'String');
			shape = contents{get(handles.Window,'Value')};
            [handles.spectrum{1}, handles.bin{1}, handles.st{1}] = ...
                        spectrogram(handles.audiodata{1}, fftsize, shape);
			[handles.spectrum{2}, handles.bin{2}, handles.st{2}] = ...
				spectrogram(handles.audiodata{2}, fftsize, shape);
			handles = makeTimePlot(handles);
			handles = makeSpecPlot(handles);
			linkedzoom([handles.timeplot, handles.specplot],'onx');
			headtext = [ handles.audiodata{1}.filenamepath '  Duration: ' ...
						 num2str(length(handles.audiodata{1}.data)/handles.audiodata{1}.Fs) ' s'...  
						'  Fs: ' num2str(handles.audiodata{1}.Fs) ' Hz'...
						'  Channels: ' num2str(handles.audiodata{1}.channels)...
						'  Bits: ' num2str(handles.audiodata{1}.nBits)];
            set(f, 'Name', headtext);
            set(handles.freqzoom,'Value',1.0);
		case 'freqbox'
            if isfield(handles,'audiodata'),
                contents = get(handles.fftsize,'String');
			    fftsize = str2double(contents{get(handles.fftsize,'Value')});
                contents = get(handles.Window,'String');
			    shape = contents{get(handles.Window,'Value')};
				handles.audiodata{2}.data = synthSpeech(handles);
				[handles.spectrum{2}, handles.bin{2}, handles.st{2}] = ...
                        spectrogram(handles.audiodata{2}, fftsize, shape);
				updateTimePlot(handles);
				updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                swsexpofn 'freqzoom';
            end
        case 'freqzoom'
			if isfield(handles,'audiodata')
				val = get(handles.freqzoom,'Value');
				if val == 0,
					val = 0.001;
				end
				Fs = handles.audiodata{1}.Fs;
				set(handles.specplot,'YLim',[0 val*Fs/2])
			end
		case 'plotmenu'
            if isfield(handles,'audiodata'),
				updateTimePlot(handles);
				updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                swsexpofn 'freqzoom';
            end
		case {'playoriginal','playsynth'}
            if isfield(handles,'audiodata'),
                times = get(handles.timeplot,'XLim');
                switch action
                    case 'playoriginal'
                        audiodata = handles.audiodata{1};
                        button = handles.play_original;
                    case 'playsynth'
                        audiodata = handles.audiodata{2};
                        button = handles.play_synth;
                end

				samples = floor(times*audiodata.Fs);
				if (samples(1) <= 0) 
					samples(1) = 1;
				end
				if (samples(2) > length(audiodata.data))
					samples(2) = length(audiodata.data);
				end
				audiodata.data = audiodata.data(samples(1):samples(2));
				if (max(abs(audiodata.data)) > 1.0)
					audiodata.data = normalize(audiodata.data);
				end
				play_audiodata(audiodata, button);
            end
		case {'db','inverse','interpolate','colormap'}
			if isfield(handles,'audiodata'),
				updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                swsexpofn 'freqzoom';
			end
		case {'fftsize','window'}
			if isfield(handles,'audiodata')
                contents = get(handles.fftsize,'String');
			    fftsize = str2double(contents{get(handles.fftsize,'Value')});
                contents = get(handles.Window,'String');
			    shape = contents{get(handles.Window,'Value')};
				handles.audiodata{2}.data = synthSpeech(handles);
                [handles.spectrum{1}, handles.bin{1}, handles.st{1}] = ...
                        spectrogram(handles.audiodata{1}, fftsize, shape);
				[handles.spectrum{2}, handles.bin{2}, handles.st{2}] = ...
                        spectrogram(handles.audiodata{2}, fftsize, shape);
				updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                swsexpofn 'freqzoom';
			end
		case 'zoomreset'
            if isfield(handles,'audiodata')
                handles = makeTimePlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                linkedzoom([handles.timeplot, handles.specplot],'onx');
            end
		case 'save'
			if isfield(handles, 'audiodata')
				save_audiodata(handles.audiodata{2});
			end
		case 'print'
			print_figure(f);
		case 'close'
			close_figure(f,figname(1:end-4));
			return;
	end
	set(f,'UserData',handles);

% --------------------------------------------------------------------
function handles = analyze(handles)
	[handles.F,handles.M] = swsmodel(handles.audiodata{1}.data, handles.audiodata{1}.Fs);
	%[handles.F,handles.M] = swsmodel2(audiodata,Fs,16,128);
	handles.audiodata{2}.data = synthSpeech(handles);
    handles.audiodata{2}.Fs = handles.audiodata{1}.Fs;
	handles.t{2} = [0:1/handles.audiodata{2}.Fs:(length(handles.audiodata{2}.data)-1)/handles.audiodata{2}.Fs];
    handles.t{1} = [0:1/handles.audiodata{1}.Fs:(length(handles.audiodata{1}.data)-1)/handles.audiodata{1}.Fs];

    function signal = synthSpeech(handles)
	comps = [];
	for i=1:4,
		if (eval(['get(handles.f' num2str(i) '_box, ''Value'');']))
			comps = cat(2,comps,i);
		end
	end
	signal = synthtrax(handles.F(comps,:),handles.M,handles.audiodata{1}.Fs);
    signal = normalize(signal);

% --------------------------------------------------------------------
function handles = makeTimePlot(handles);
	axes(handles.timeplot)
	plot(handles.t{2},handles.audiodata{2}.data)
	maxtime = length(handles.t{2})/handles.audiodata{2}.Fs;
	set(handles.timeplot,'XLim',[0 maxtime]);
	set(handles.timeplot,'YLim',[-1.0 1.0]);
	grid;
	xlabel('time (s)');

function handles = makeSpecPlot(handles);
	axes(handles.specplot);
	handles.pos = get(gca,'Position'); % Save axes position
	if (get(handles.interpolate,'Value'))
		if (get(handles.dBcheckbox,'Value'))
			pcolor(handles.st{2},handles.bin{2},20*log10(abs(handles.spectrum{2})));
		else
			pcolor(handles.st{2},handles.bin{2},abs(handles.spectrum{2}));
		end
		shading interp;
	else
		if (get(handles.dBcheckbox,'Value'))
			imagesc(handles.t{2},handles.bin{2},20*log10(abs(handles.spectrum{2})));
		else
			imagesc(handles.t{2},handles.bin{2},abs(handles.spectrum{2}));
		end
	end

	axis xy;
	ylabel('Frequency (Hz)');
	colormap('Jet');
	set(handles.specplot,'XTickLabel',['']);
	h = colorbar('vert');
	if (get(handles.dBcheckbox,'Value'))
		set(get(h, 'YLabel'), 'String', 'dB');
	else
		set(get(h, 'YLabel'), 'String', 'Amplitude');
	end
	set(handles.specplot,'Units','Characters');
	sonopos = get(handles.specplot,'Position')
	set(h,'units','Characters', ...
		'Position',[sonopos(1)+sonopos(3)+20 sonopos(2) 7 sonopos(4)]);
    switch computer
        case {'GLNX86','MAC'}
            %set(gca,'Position',handles.pos + [0 0.07 0 0])
            set(gca,'Position',handles.pos)
        case 'PCWIN'
            set(gca,'Position',handles.pos)
    end

	handles.xlim_specplot_orig = get(handles.specplot,'XLim');
	handles.ylim_specplot_orig = get(handles.specplot,'YLim');
	handles.xlim_timeplot_orig = get(handles.timeplot,'XLim');
	handles.ylim_timeplot_orig = get(handles.timeplot,'YLim');
	handles.xlim_specplot = handles.xlim_specplot_orig;
	handles.ylim_specplot = handles.ylim_specplot_orig;
	handles.xlim_timeplot = handles.xlim_timeplot_orig;
	handles.ylim_timeplot = handles.ylim_timeplot_orig;
	handles.clim = get(handles.specplot,'CLim');

% --------------------------------------------------------------------
function updateTimePlot(handles)
    handles.xlim_timeplot = get(handles.timeplot,'XLim');
	if (get(handles.plotmenu,'Value') == 2)
		audiodata = handles.audiodata{1}.data;
		t = handles.t{1};
	else
		audiodata = handles.audiodata{2}.data;
		t = handles.t{2};
	end
	axes(handles.timeplot)
	plot(t,audiodata)
	set(handles.timeplot,'XLim',handles.xlim_timeplot);
	xlabel('time (s)');
	grid;
    
function updateSpecPlot(handles)
	if (get(handles.plotmenu,'Value') == 2)
		spectrum = handles.spectrum{1};
		bin = handles.bin{1};
		t = handles.t{1};
		st = handles.st{1};
	else
		spectrum = handles.spectrum{2};
		bin = handles.bin{2};
		t = handles.t{2};
		st = handles.st{2};
	end
	axes(handles.specplot);
	% Check Interpolate and dB
	if (get(handles.interpolate,'Value'))
		if (get(handles.dBcheckbox,'Value'))
			pcolor(st,bin,20*log10(abs(spectrum)));
		else
			pcolor(st,bin,abs(spectrum));
		end
		shading interp;
	else
		if (get(handles.dBcheckbox,'Value'))
			imagesc(t,bin,20*log10(abs(spectrum)));
		else
			imagesc(t,bin,abs(spectrum));
		end
	end
	set(handles.specplot,'XTickLabel',['']);
	axis xy;
	ylabel('Frequency (Hz)');
	% Get Colormap
	contents = get(handles.colormap,'String');
	cmap = colormap(lower(contents{get(handles.colormap,'Value')}));
	% Handle Inverse
	if (get(handles.inverse,'Value'))
		colormap(flipud(cmap));
	else
		colormap(cmap);
	end
	set(handles.specplot,'XLim',handles.xlim_specplot);
	set(handles.specplot,'YLim',handles.ylim_specplot);
	% The following makes too dark original signal plot.
	%set(handles.specplot,'CLim',handles.clim);
	h = colorbar('vert');
	if (get(handles.dBcheckbox,'Value'))
		set(get(h, 'YLabel'), 'String', 'dB');
	else
		set(get(h, 'YLabel'), 'String', 'Amplitude');
	end
	set(handles.specplot,'Units','Characters');
	sonopos = get(handles.specplot,'Position')
	set(h,'units','Characters', ...
		'Position',[sonopos(1)+sonopos(3)+20 sonopos(2) 7 sonopos(4)]);
    switch computer
        case {'GLNX86','MAC'}
            %set(gca,'Position',handles.pos + [0 0.07 0 0])
            set(gca,'Position',handles.pos)
        case 'PCWIN'
            set(gca,'Position',handles.pos)
    end