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

    function wavexpofn(action)

	if nargin < 1
		action='init';
	end

	% Add a volume slider, zoom scrollbar
	% Make more dynamic with user input number of sliders

	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;
			handles.comp = 15;
			handles.f = [440 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
			handles.a = [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
			handles.p = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
			handles.dur = 1;
			handles.Fs = 44100;
			handles.t = [0:handles.Fs*handles.dur-1]./handles.Fs;
			set(f,'UserData',handles);
			wavexpofn 'update'
		case 'update'
			handles = update_signal(handles);
			set(f,'UserData',handles);
			update_plot(handles);
			update_controls(handles);
		case 'waveform'
			handles = getwaveform(handles);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'play'
			signal = zeros(1,handles.Fs*handles.dur);
			handles.t = [0:handles.Fs*handles.dur-1]./handles.Fs;
			t = handles.t;
			for i=1:handles.comp
				signal = signal + handles.a(i).*sin(2*pi*t.*handles.f(i) + handles.p(i)*pi/180);
			end
			if (max(abs(signal)) > 1.0)
				signal = signal./max(abs(signal)+0.4);
			end
			if(isunix)
				signal(length(signal):length(signal)+handles.Fs) = 0;
				p = handle(com.mathworks.toolbox.audio.JavaAudioPlayer(signal,handles.Fs,16));
				p.play;
			else
				sound(signal,handles.Fs);
			end
		case 'write_soundfile'
			[filename, pathname] = uiputfile('*.wav', 'Save sound as');
			if isequal(filename,0) | isequal(pathname,0)
				return;
			end
			signal = zeros(1,handles.Fs*handles.dur);
			handles.t = [0:handles.Fs*handles.dur-1]./handles.Fs;
			t = handles.t;
			for i=1:handles.comp
				signal = signal + handles.a(i).*sin(2*pi*t.*handles.f(i) + handles.p(i)*pi/180);
			end
			wavwrite(signal,handles.Fs,16,[pathname filename]);
			disp(['File saved as ', fullfile(pathname, filename)])
		case {'fourier','sonogram','alias'}
			signal = zeros(1,handles.Fs*handles.dur);
			t = handles.t;
			for i=1:handles.comp,
				signal = signal + handles.a(i).*sin(2*pi*t.*handles.f(i) + handles.p(i)*pi/180);
			end
			if (max(signal) > 1.0)
				signal = normalize(signal);
			end
			audiodata.data = signal';
			audiodata.Fs = handles.Fs;
			switch action
				case 'fourier'
					fourierexpogui(audiodata);
				case 'sonogram'
					sonoexpogui(audiodata);
                case 'alias'
                    aliasexpogui(audiodata);
			end
		case 'fslider'
			textnum = handles.textnum;
			eval(['val = get(handles.f' num2str(textnum) ',''Value'');']);
            if 2^val-2^4.3219 < 0
                val = 4.3219;
            elseif 2^val-2^4.3219 > 22050
                val = 14.4285;
            end
			eval(['handles.f(' num2str(textnum+1) ') = 2^val-2^4.3219;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'ftext'
			textnum = handles.textnum;
			eval(['val = str2double(get(handles.f' num2str(textnum) 't,''String''));']);
            if val < 0
                val = 0;
            elseif val > 22030
                val = 22030;    
            end
			eval(['handles.f(' num2str(textnum+1) ') = val;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'aslider'
			textnum = handles.textnum;
			eval(['val = get(handles.a' num2str(textnum) ',''Value'');']);
			eval(['handles.a(' num2str(textnum+1) ') = val;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'atext'
			textnum = handles.textnum;
			eval(['val = str2double(get(handles.a' num2str(textnum) 't,''String''));']);
			eval(['handles.a(' num2str(textnum+1) ') = val;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'pslider'
			textnum = handles.textnum;
			eval(['val = get(handles.p' num2str(textnum) ',''Value'');']);
			eval(['handles.p(' num2str(textnum+1) ') = val;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'ptext'
			textnum = handles.textnum;
			eval(['val = str2double(get(handles.p' num2str(textnum) 't,''String''));']);
			eval(['handles.p(' num2str(textnum+1) ') = val;']);
			set(f,'UserData',handles);
			wavexpofn 'update';
		case 'randomizephase'
			for i=1:handles.comp,
				val = 2*180*(0.5 - rand);
				handles.p(i) = val;
				eval(['set(handles.p' num2str(i-1) 't,''String'',num2str(val));']);
				eval(['set(handles.p' num2str(i-1) ',''Value'',val);']);
			end
			handles = update_signal(handles);
			update_plot(handles);
	end
	set(f,'UserData',handles);


% --------------------------------------------------------------------
function handles = update_signal(handles)
	signal = zeros(1,handles.Fs*handles.dur);
	t = handles.t;
	for i=1:handles.comp,
		signal = signal + handles.a(i).*sin(2*pi*t.*handles.f(i) + handles.p(i)*pi/180);
	end
	handles.signal = signal;

function update_controls(handles)
	for i=1:handles.comp
		eval(['set(handles.f' num2str(i-1) ',''Value'', log2(handles.f(' num2str(i) ')+20));']);
		eval(['set(handles.f' num2str(i-1) 't,''String'', num2str(handles.f(' num2str(i) '),6));']);
		eval(['set(handles.a' num2str(i-1) ',''Value'', handles.a(' num2str(i) '));']);
		eval(['set(handles.a' num2str(i-1) 't,''String'', num2str(handles.a(' num2str(i) '),4));']);
		eval(['set(handles.p' num2str(i-1) ',''Value'', handles.p(' num2str(i) '));']);
		eval(['set(handles.p' num2str(i-1) 't,''String'', num2str(handles.p(' num2str(i) '),4));']);
	end

function update_plot(handles)
	axes(handles.waveplot);
	signal = handles.signal;
	nonzero = find(handles.a > 0 & handles.f > 0);
    if ~isempty(nonzero)
	    xlim = [0 10/min(handles.f(nonzero))];
    else
        xlim = [0 1];    
    end
	plot(handles.t,signal);
	set(handles.waveplot,'XLim',xlim);
	maxval = max(abs(signal));
	set(handles.waveplot,'YLim',[-1.5 1.5]);
	if (maxval > 1.5)
		set(handles.waveplot,'YLim',[-maxval-0.1 maxval+0.1]);
	end
	xlabel('Time (s)');
	grid; zoom on;

% --------------------------------------------------------------------
function handles = getwaveform(handles)
	contents = get(handles.waveform,'String');
	switch (lower(contents{get(handles.waveform,'Value')}))
		case 'sine'
			handles.a(1) = 1;
			handles.p(1) = 0;
			for i=2:handles.comp
				handles.a(i) = 0;
				handles.f(i) = 20;
				handles.p(i) = 0;
			end
		case 'square'
			fundamental = handles.f(1);
			for i=1:handles.comp
				partial = 2*i-1;
				handles.a(i) = 1/partial;
				if (handles.a(i) > 1)
					handles.a(i) = 1;
				end
				handles.f(i) = fundamental*partial;
				if (handles.f(i) > 22050)
					handles.f(i) = 22050;
					handles.a(i) = 0;
				end
				handles.p(i) = 0;
			end
		case 'triangle'
			fundamental = handles.f(1);
			for i=1:handles.comp
				partial = 2*i-1;
				handles.a(i) = (1/partial)^2;
				handles.f(i) = fundamental*partial;
				if (handles.f(i) > 22050)
					handles.f(i) = 22050;
					handles.a(i) = 0;
				end
				handles.p(i) = -90;
			end
		case 'sawtooth'
			fundamental = handles.f(1);
			for i=1:handles.comp
				partial = i;
				handles.a(i) = 1/(partial*2);
				handles.f(i) = fundamental*partial;
				if (handles.f(i) > 22050)
					handles.f(i) = 22050;
					handles.a(i) = 0;
				end
				handles.p(i) = 0;
			end
		case 'impulse'
			fundamental = handles.f(1);
			for i=1:handles.comp
				partial = i;
				handles.a(i) = 1;
				handles.f(i) = fundamental*partial;
				if (handles.f(i) > 22050)
					handles.f(i) = 22040;
					handles.a(i) = 0;
				end
				handles.p(i) = 0;
			end
		case 'random'
			fundamental = handles.f(1);
			for i=1:handles.comp
				partial = i + rand;
				handles.a(i) = 1/partial;
				handles.f(i) = fundamental*partial;
				if (handles.f(i) > 22050)
					handles.f(i) = 22050;
					handles.a(i) = 0;
				end
				handles.p(i) = (0.5 - rand)*360;
			end
	end