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

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

	% Program this to use the replace 'XData' routine to make it faster!
	% Play, finish; Press play again doesn't restart!
	% When wwidth2 > wwidth1, no work?

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

	switch action
		case 'help'
			display_help(figname);
		case 'init'
			setdefaults;
            movegui(f,'center');
			handles.wave1 = makewave(handles,1);
			handles.wave2 = makewave(handles,2);
			wwidth1 = str2double(get(handles.width1, 'String'));
			wwidth2 = str2double(get(handles.width2, 'String'));
			handles.wave3 = zeros(1,2*wwidth2+wwidth1);
			handles.stepnum = -1;
			% Update handles structure
			handles = plotwave(handles,1);
			handles = plotwave(handles,2);
			handles = plotwave(handles,3);
		case 'readinput'
			if isfield(datastruct,'impulse')
				impulse = datastruct.impulse;
				clear datastruct;
				handles.stepnum = -1;
				wwidth1 = str2double(get(handles.width1, 'String'));
				wwidth2 = length(impulse);
				set(handles.grid,'Value',0);
				set(handles.showshape,'Value',1);
				set(handles.width2,'String',num2str(wwidth2));
				handles.wave2 = impulse;
				handles = plotwave(handles,2);
				handles = plotwave(handles,1);
				handles.wave3 = zeros(1,2*wwidth2+wwidth1);
				handles = plotwave(handles,3);
				% Set menu to custom
				contents = get(handles.pulse2_type,'String');
				a = find(strcmp(contents,'custom'));
				set(handles.pulse2_type,'Value',a);
			end
		case 'stepforw'
			wwidth1 = str2double(get(handles.width1, 'String'));
			wwidth2 = str2double(get(handles.width2, 'String'));
			stepnum = handles.stepnum;
			stepnum = stepnum + 1;
			if (stepnum < wwidth1+wwidth2+1)
				handles.stepnum = stepnum;
				plotwave(handles,2);
				handles.wave3(stepnum+1) = calcconv(handles,stepnum);
				plotwave(handles,3);
			end
		case 'stepback'
			stepnum = handles.stepnum;
			stepnum = stepnum - 1;
			if (stepnum > -1)
				handles.stepnum = stepnum;
				handles.wave3(stepnum+1) = calcconv(handles,stepnum);
				handles.wave3(stepnum+2:end) = 0;
				plotwave(handles,2);
				plotwave(handles,3);
			elseif (stepnum == -1)
				handles.stepnum = stepnum;
				plotwave(handles,2);
                plotwave(handles,3);
			end
		case {'width1','width2','pulse1','pulse2','reset'}
			wwidth1 = str2double(get(handles.width1, 'String'));
			wwidth2 = str2double(get(handles.width2, 'String'));
			handles.wave3 = zeros(1,2*wwidth2+wwidth1);
			handles.stepnum = -1;
			switch action
				case {'width1','pulse1'}
					handles.wave1 = makewave(handles,1);
				case {'width2','pulse2'}
					handles.wave2 = makewave(handles,2);
			end
			plotwave(handles,1);
			plotwave(handles,2);
			plotwave(handles,3);
		case 'play'
            stepnum = handles.stepnum;
            if (strcmp(get(handles.play,'String'),'Play'))
                set(handles.play,'String','Stop');
            else
                set(handles.play,'String','Play');
            end

			stepnum = handles.stepnum;
			wwidth1 = str2double(get(handles.width1, 'String'));
			wwidth2 = str2double(get(handles.width2, 'String'));
			if stepnum > wwidth1+wwidth2,
				stepnum = -1;
			end

			if get(handles.cyclic,'Value')
				playlimit = max([wwidth1 wwidth2]);
			else
				playlimit = wwidth1+wwidth2;
			end

			while (stepnum < playlimit & strcmp(get(handles.play,'String'),'Stop'))
				stepnum = stepnum+1;
				handles.stepnum = stepnum;
				handles.wave3(stepnum+1) = calcconv(handles,stepnum);
				plotwave(handles,2);
				plotwave(handles,3);
				drawnow;
			end
			%handles.wave3 = [handles.wave3 zeros(1,length(handles.wave2))];
			plotwave(handles,3);
		    set(handles.play,'String','Play');
        case 'showshape'
            plotwave(handles,1);
			plotwave(handles,2);
            plotwave(handles,3);
        case 'cyclic'
			handles.stepnum = -1;
            plotwave(handles,1);
			plotwave(handles,2);
            plotwave(handles,3);
        case 'grid'
            plotwave(handles,1);
			plotwave(handles,2);
            plotwave(handles,3);
		case 'close'
			close_figure(f,figname(1:end-4));
            return;
	end
	set(f,'UserData',handles);

% --------------------------------------------------------------------
function handles = plotwave(handles,signum)
	eval(['axes(handles.axes' num2str(signum) ');']);
	data = eval(['handles.wave' num2str(signum) ]);
	stepnum = handles.stepnum;
	wwidth1 = str2double(get(handles.width1, 'String'));
	wwidth2 = str2double(get(handles.width2, 'String'));

    if (signum == 1)
		if get(handles.cyclic,'Value')
			if wwidth1 < wwidth2,
				data = [data zeros(1,wwidth2-wwidth1)];
			end
		else
			data = [zeros(1,wwidth2) data zeros(1,wwidth2)];
		end

        if (get(handles.showshape,'Value'))
            plot(data);
        else
		    stem(data);
        end
    end

	if (signum == 2)
		if get(handles.cyclic,'Value')
			if wwidth2 < wwidth1,
				data = [data zeros(1,wwidth1-wwidth2)];
			end

			if stepnum == -1,
				stepnum = 0;
			elseif stepnum >= 0 & stepnum < wwidth1,
				data = fliplr(data);
				data = [data(wwidth1-stepnum+1:end) data(1:wwidth1-stepnum)];
			elseif stepnum == wwidth1,
				data = data;
				data = fliplr(data);
			end
		else
			if stepnum == -1,
				stepnum = 0;
				data = [data zeros(1,wwidth1+wwidth2)];
			else
				data = [zeros(1,stepnum) fliplr(data) zeros(1,wwidth1+wwidth2-stepnum)];
			end
		end

        if (get(handles.showshape,'Value'))
            plot(data);
        else
		    stem(data);
        end
	elseif (signum == 3)
		if stepnum == -1,
			cla;
		elseif (get(handles.showshape,'Value'))
            plot(data);
        else
		    stem(data);
        end
	end

	if get(handles.cyclic,'Value'),
		if wwidth1 > wwidth2,
			if wwidth1 > 1,
				xlim([1 wwidth1]);
			else
				%xlim([1 wwidth1+1]);
			end
		else
			if wwidth2 > 1,
				xlim([1 wwidth2]);
			else
				%xlim([1 wwidth2+1]);
			end
		end
	else
		xlim([1 2*wwidth2+wwidth1]);
	end

	if max(abs(data))<1 & max(abs(data))>0 & signum ~= 3,
		ylim([-max(abs(data))*1.1 max(abs(data))*1.1]);
	elseif max(abs(data)) > 1
		ylim([-max(abs(data))*1.1 max(abs(data))*1.1]);
	else
		ylim([-1.1 1.1]);
	end
    
	if (signum == 3)
		set(gca,'XTick',[1:2*wwidth2+wwidth1])
		set(gca,'XTickLabel',[0:2*wwidth2+wwidth1-1])
        if stepnum > 1
		    xlabel('Sample');
        end
	else
		set(gca,'XTick',[1:2*wwidth2+wwidth1])
		set(gca,'XTickLabel',' ')
	end
    
    if (get(handles.grid,'Value'))
	    grid on;
    else
        set(gca,'XTick',[])
		set(gca,'XTickLabel',' ')
        set(gca,'YTick',[])
		set(gca,'YTickLabel',' ')
    end


% --------------------------------------------------------------------
function wave = makewave(handles,signum)
	wwidth = str2double(eval(['get(handles.width' num2str(signum) ',''String'')']));
	wave = zeros(1,wwidth);
	
	contents = eval(['get(handles.pulse' num2str(signum) '_type,''String'')']);
	type = contents{eval(['get(handles.pulse' num2str(signum) '_type,''Value'')'])};

	switch lower(type),
		case 'square'
			wave = ones(1,wwidth);
		case 'triangle'
			wave(1:wwidth) = triang(wwidth)*(1/min(triang(wwidth)));
			wave = wave./max(wave);
		case 'sine1'
			wave(1:wwidth) = sin(2*pi*(0:1/wwidth:1-1/wwidth));
		case 'sine2'
			wave(1:wwidth) = sin(2*pi*(0:1/wwidth:1-1/wwidth)*1.5);
		case 'sine3'
			wave(1:wwidth) = sin(2*pi*(0:1/wwidth:1-1/wwidth)*4);
		case 'random'
			wave(1:wwidth) = 0.5 - rand(1,wwidth);
		otherwise
			% Impulse designer?
	end	


% --------------------------------------------------------------------
function value = calcconv(handles,stepnum)
	wwidth1 = str2double(get(handles.width1, 'String'));
	wwidth2 = str2double(get(handles.width2, 'String'));
	if get(handles.cyclic,'Value')
		data1 = handles.wave1;
		data2 = handles.wave2;
		if wwidth1 < wwidth2,
			data1 = [data1 zeros(1,wwidth2-wwidth1)];
		end

		if wwidth2 < wwidth1,
			data2 = [data2 zeros(1,wwidth1-wwidth2)];
		end

		if stepnum > 0 & stepnum < wwidth1+wwidth2,
			data2 = [data2(stepnum+1:end) data2(1:stepnum)];
		end
	else
		data1 = [zeros(1,wwidth2) handles.wave1 zeros(1,wwidth2)];
		data2 = [zeros(1,stepnum) fliplr(handles.wave2) zeros(1,wwidth1+wwidth2-stepnum)];
	end
	value = sum(data1.*data2);