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

    % This code borrows heavily from MAD polezero demonstration
function pzfilterexpo(action,datastruct)
    if nargin < 1
        action='init';
    end

	% Colormap isn't working as predicted

    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);
			reset(handles.pz_plot);
			reset(handles.Hz_plot);
			handles.Fs = 44100;
			handles.npoints = 256;
			makePZPlot(handles);
			handles = makeHzPlot(handles);
			set(gcf,'KeyPressFcn','pzfilterexpofn keypressed');
		case 'loadsound'
			handles.audiodata = load_audiodata;
            handles.original = handles.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.Fs = handles.audiodata.Fs;
            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, handles.bin, handles.st] = ...
                spectrogram(handles.audiodata, fftsize, shape);
            handles = makeTimePlot(handles);
            handles = makeSpecPlot(handles);
            handles = makeHzPlot(handles);
            handles = updateHzPlot(handles);
            linkedzoom([handles.timeplot, handles.specplot],'onx');
            place_header(f,handles);
            set(handles.freqzoom,'Value',1);
		case 'readinput'
			if isfield(datastruct,'polepos')
				handles.Fs = 44100;
				handles = makeHzPlot(handles);
                if isfield(datastruct, 'gain')
                    set(handles.gain,'String',num2str(datastruct.gain));
                end
				z = datastruct.zeropos; 
				% Remove zeros from 0
				z = z(find(z));
				zc = conj(z);
				elem = find(z == zc);
				if (elem > 0) 
					% Add just a bit so that the plot doesn't make them invisible
					mult = 0.00000;
					z = [z(1:elem-1); z(elem)+j*mult; z(elem)-j*mult; z(elem+1:end)];
					datastruct.zeropos = z;
				end 
				p = datastruct.polepos;
				% Remove poles from 0
				p = p(find(p));
				pc = conj(p);
				elem = find(p == pc);
				if (elem > 0)
					mult = 0.00000;
					p = [p(1:elem-1); p(elem)+j*mult; p(elem)-j*mult; p(elem+1:end)];
					datastruct.polepos = p;
				end

				for i=1:length(datastruct.zeropos)/2,
					x = real(datastruct.zeropos(i*2-1));
					y = imag(datastruct.zeropos(i*2-1));
					p1=text('Parent',handles.pz_plot,'Position',[x y],...
						'String','o','ButtonDownFcn','pzfilterexpofn selectzero',...
						'EraseMode','xor','Tag','Zero',...
						'HorizontalAlignment','center');
					if y ~= 0,
						p2=text('Parent',handles.pz_plot,'Position',[x -y],...
							'String','o','ButtonDownFcn','pzfilterexpofn selectzero',...
							'EraseMode','xor','Tag','Zero',...
							'HorizontalAlignment','center');
						set(p1,'UserData',p2);
						set(p2,'UserData',p1);
					end
				end
				for i=1:length(datastruct.polepos)/2,
					x = real(datastruct.polepos(i*2-1));
					y = imag(datastruct.polepos(i*2-1));
					p1=text('Parent',handles.pz_plot,'Position',[x y],...
						'String','x','ButtonDownFcn','pzfilterexpofn selectpole',...
						'EraseMode','xor','Tag','Pole',...
						'HorizontalAlignment','center');
					if y ~= 0,
						p2=text('Parent',handles.pz_plot,'Position',[x -y],...
							'String','x','ButtonDownFcn','pzfilterexpofn selectpole',...
							'EraseMode','xor','Tag','Pole',...
							'HorizontalAlignment','center');
						set(p1,'UserData',p2);
						set(p2,'UserData',p1);
					end
				end
				handles = updateHzPlot(handles);
			else
				handles.audiodata = datastruct;
				clear datastruct;
				if (size(handles.audiodata.data,2) > 1)
					handles.audiodata.data = to_mono(handles.audiodata.data);
				end
				handles.original = 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.spectrum, handles.bin, handles.st] = ...
					spectrogram(handles.audiodata, fftsize, shape);
				handles = makeTimePlot(handles);
				handles = makeSpecPlot(handles);
				handles = makeHzPlot(handles);
				handles = updateHzPlot(handles);
            	linkedzoom([handles.timeplot, handles.specplot],'onx');
            	place_header(f,handles);
            	set(handles.freqzoom,'Value',1);
			end
        case {'playsound', 'playoriginal'}
            if isfield(handles, 'audiodata')
                times = get(handles.specplot,'XLim');
                switch action
                    case 'playsound'
                        audiodata = handles.audiodata;
                        button = handles.play;
                    case 'playoriginal'
                        audiodata = handles.original;
                        button = handles.playoriginal;
                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','fftdisplay'}
			if isfield(handles, 'audiodata')
                updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                pzfilterexpofn 'freqzoom';
            end
		case 'Hz_logf'
			if get(handles.Hz_logf,'Value')
				set(handles.Hz_plot,'XScale','log');
			else
				set(handles.Hz_plot,'XScale','linear');
			end
        case 'Hz_dB'
            axes(handles.Hz_plot);
			if get(handles.dB,'Value')
				set(handles.Hz_plot,'YLim',[-80 1]);
    			ylabel('Normalized Attenuation (dB)');
			else
				%set(handles.freq_plot,'YLim',[0 1.05]);
                %set(handles.freq_plot,'YLimMode','auto');
    			ylabel('Normalized Attenuation');
			end
			pzfilterexpofn 'plotfreqz'
		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.spectrum, handles.bin, handles.st] = ...
                    spectrogram(handles.audiodata, fftsize, shape);
                updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                pzfilterexpofn 'freqzoom';
            end
		case 'normalize'
            if isfield(handles, 'audiodata')
				handles.audiodata.data = normalize(handles.audiodata.data);
				handles = makeTimePlot(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, handles.bin, handles.st] = ...
                    spectrogram(handles.audiodata, fftsize, shape);
                updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                pzfilterexpofn 'freqzoom';
			end
		case 'freqzoom' 
            if isfield(handles,'audiodata')
                val = get(handles.freqzoom,'Value');
                if val == 0,
                    val = 0.001; 
                end
                Fs = handles.audiodata.Fs;
                set(handles.specplot,'YLim',[0 val*Fs/2])
            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 'fourier'
			if isfield(handles,'audiodata')
				fourierexpogui(handles.audiodata);
			end
		case 'addzero'
			handles = add_coef(handles,'zero');
			pzfilterexpofn 'plotfreqz'
		case 'addpole'
			handles = add_coef(handles,'pole');
			pzfilterexpofn 'plotfreqz'
		case 'selectpole'
			handles = select_coef(handles,'pole');
		case 'selectzero'
			handles = select_coef(handles,'zero');
		case 'movepole'
			handles = move_coef(handles);
			pzfilterexpofn 'plotfreqz'
		case 'movezero'
			handles = move_coef(handles);
			pzfilterexpofn 'plotfreqz'
		case 'releaseobject'
			set(gcf,'WindowButtonMotionFcn','');
			set(gcf,'WindowButtonUpFcn','');
			%set([handles.currentcoef handles.partnercoef],'Selected','off');
			pzfilterexpofn 'plotfreqz'
		case 'plotfreqz'
			handles = updateHzPlot(handles);
		case 'loadvowel'
			axes(handles.pz_plot);
			cla;
			delete(findobj(gcf,'Selected','on'))
			makePZPlot(handles);
			bws=[0.03 0.07 0.1];    %formant freqs from Rabiner & Juang
			switch datastruct
				case 'beet'
					freqs=[270 2290 3010];
				case 'bit'
					freqs=[390 1990 2550];
				case 'bet'
					freqs=[530 1840 2480];
				case 'bat'
					freqs=[660 1720 2410];
				case 'bart'
					freqs=[730 1090 2440];
				case 'bort'
					freqs=[570 840 2410];
				case 'but'
					freqs=[440 1020 2240];
				case 'boot'
					freqs=[300 870 2240];
				case 'bert'
					freqs=[490 1350 1690];
				otherwise
			end
			% convert freqs and bws to PZ locations
			angs=2*pi*freqs/handles.Fs;
			for fr=1:length(freqs)
				[x,y]=pol2cart(angs(fr),1-bws(fr));
				p1=text('Parent',handles.pz_plot,'Position',[x y],...
					'String','x','ButtonDownFcn','pzfilterexpofn selectpole',...
					'EraseMode','xor','Tag','Pole','HorizontalAlignment','center');
				p2=text('Parent',handles.pz_plot,'Position',[x -y],...
					'String','x','ButtonDownFcn','pzfilterexpofn selectpole',...
					'EraseMode','xor','Tag','Pole','HorizontalAlignment','center');
				set(p1,'UserData',p2);
				set(p2,'UserData',p1);
			end
            handles = updateHzPlot(handles);
		case 'apply_filter'
            if isfield(handles, 'audiodata')
                handles = apply_filter(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, handles.bin, handles.st] = ...
                    spectrogram(handles.audiodata, fftsize, shape);
                updateSpecPlot(handles);
                Xlim = get(handles.timeplot,'XLim');
                handles = makeTimePlot(handles);
                set(handles.specplot,'XLim',Xlim);
                set(handles.timeplot,'XLim',Xlim);
                pzfilterexpofn 'freqzoom';
            end
		case 'keypressed'
			% if delete key is pressed, delete any selected object
				if double(get(gcf,'CurrentCharacter')) == 8
					delete(findobj(gcf,'Selected','on'))
				end
				pzfilterexpofn 'plotfreqz'
        case 'save'
            if isfield(handles.audiodata,'data')
				save_audiodata(handles.audiodata);
			end
		case 'undo'
            if isfield(handles,'audiodata')
			    handles = undo(handles);
			    updateSpecPlot(handles);
                Xlim = get(handles.timeplot,'XLim');
			    handles = makeTimePlot(handles);
                set(handles.specplot,'XLim',Xlim);
                set(handles.timeplot,'XLim',Xlim);
                pzfilterexpofn 'freqzoom';
            end
		case 'convexpo'
			polepos=findobj(handles.pz_plot,'Tag','Pole');
            zeropos=findobj(handles.pz_plot,'Tag','Zero');
            pp = [];
            zz = []; 
            for p=1:length(polepos) 
                ppos=get(polepos(p),'Position');
                pp(p)=complex(ppos(1),ppos(2));
            end 
            for z=1:length(zeropos) 
                zp=get(zeropos(z),'Position');
                zz(z)=complex(zp(1),zp(2));
            end
			[num,den]=zp2tf(zz',pp',1);
			data.impulse = filter(num, den,[1 zeros(1,99)]);
			convexpogui(data);
		case 'pzexpo'
			polepos=findobj(handles.pz_plot,'Tag','Pole');
            zeropos=findobj(handles.pz_plot,'Tag','Zero');
            pp = [];
            zz = []; 
            for p=1:length(polepos) 
                ppos=get(polepos(p),'Position');
                pp(p)=complex(ppos(1),ppos(2));
            end 
            for z=1:length(zeropos) 
                zp=get(zeropos(z),'Position');
                zz(z)=complex(zp(1),zp(2));
            end
            data.polepos = pp;
            data.zeropos = zz;
            data.gain = str2num(get(handles.gain,'String'));
            pzexpogui(data);
		case 'unselectall'
            set(findobj(gcf,'Selected','on'),'Selected','off');
		case 'print'
			print_figure(f);
		case 'close'
			close_figure(f,figname(1:end-4));
            return;
	end
	set(f,'UserData',handles);

% --------------------------------------------------------------------
function makePZPlot(handles)
	axes(handles.pz_plot);
	set(handles.pz_plot, 'DrawMode','fast', 'NextPlot','replacechildren',...
		'Box','on', 'XLim', [-1.3 1.3], 'YLim', [-1.3 1.3]);

	cax=handles.pz_plot;
	% define a circle
	th = 0:pi/50:2*pi;
	xunit = cos(th);
	yunit = sin(th);
	rmax=1;
	tc = get(cax,'xcolor');

	% now really force points on x/y axes to lie on them exactly
	inds = 1:(length(th)-1)/4:length(th);
	xunit(inds(2:2:4)) = zeros(2,1);
	yunit(inds(1:2:5)) = zeros(3,1);

	patch('xdata',xunit*rmax,'ydata',yunit*rmax, ...
		'edgecolor',tc,'facecolor',get(gca,'color'),...
		'ButtonDownFcn','pzfilterexpofn unselectall');

	line([-1.1 1.1],[0 0]);
	line([0 0],[-1.1 1.1]);
	axis(rmax*[-1 1 -1.15 1.15]);
	axis image;
	axis off;
	zoom off;


function handles = makeHzPlot(handles);
    if isfield(handles, 'audiodata')
        Fs = handles.audiodata.Fs;
    else
        Fs = handles.Fs;
    end
	axes(handles.Hz_plot);
    cla;
	handles.freqs=linspace(0,Fs/2,handles.npoints);
	handles.magline=line(handles.freqs,zeros(size(handles.freqs)));
	set(handles.magline,'EraseMode','xor');
	axis normal;	% Strange hack.
	set(handles.Hz_plot,'XLim',[0 round(Fs/2)]);
	set(handles.Hz_plot, 'DrawMode','fast', 'NextPlot','replacechildren',...
		'Box','off');
	xlabel('frequency (Hz)');
    ylabel('Attenuation');


% --------------------------------------------------------------------
function handles = makeTimePlot(handles);
	handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/...
			handles.audiodata.Fs];
    axes(handles.timeplot) 
    plot(handles.t,handles.audiodata.data)
    maxtime = length(handles.t)/handles.audiodata.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,handles.bin,20*log10(abs(handles.spectrum)));
        else
            pcolor(handles.st,handles.bin,abs(handles.spectrum));
        end
        shading interp;
    else
        if (get(handles.dBcheckbox,'Value'))
            imagesc(handles.t,handles.bin,20*log10(abs(handles.spectrum)));
        else
            imagesc(handles.t,handles.bin,abs(handles.spectrum));
        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)+18 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 ud = updateHzPlot(ud)
    polepos=findobj(ud.pz_plot,'Tag','Pole');
    zeropos=findobj(ud.pz_plot,'Tag','Zero');
    len=max(length(polepos),length(zeropos));
    pp=zeros(1,len);  % pp=1e-10*rand(1,len);
    for p=1:length(polepos)
        ppos=get(polepos(p),'Position');
        pp(p)=ppos(1)+ppos(2)*i;
    end
    zz=zeros(1,len);  % zz=1e-10*rand(1,len);
    for z=1:length(zeropos)
        zp=get(zeropos(z),'Position');
        zz(z)=zp(1)+zp(2)*i;
    end
    ud.zz=zz;ud.pp=pp;
    [ud.num,ud.den]=zp2tf(zz',pp',1);
    [h,w]=freqz(ud.num,ud.den,ud.freqs,ud.Fs);
    gain = str2num(get(ud.gain,'String'));
    if get(ud.dB,'Value')
		% normalise so max = 0 dB
		logmag=20*log10(abs(h));
		mag=logmag-max(logmag);
	else
		mag = gain*abs(h)./max(abs(h));
        %mag = gain*abs(h);
        set(ud.Hz_plot,'YLim',[0 max(mag)*1.1]);
	end
    set(ud.magline,'YData',mag);


function updateTimePlot(handles)
	axes(handles.timeplot)
	plot(handles.t,handles.audiodata)
	set(handles.timeplot,'XLim',handles.xlim_timeplot);
	set(handles.timeplot,'YLim',handles.ylim_timeplot);
	xlabel('time (s)');
	grid;


function updateSpecPlot(handles)
    axes(handles.specplot);
	if (get(handles.interpolate,'Value'))
		if (get(handles.dBcheckbox,'Value'))
			pcolor(handles.st,handles.bin,20*log10(abs(handles.spectrum)));
		else
			pcolor(handles.st,handles.bin,abs(handles.spectrum));
		end
		shading interp;
	else
		if (get(handles.dBcheckbox,'Value'))
			imagesc(handles.t,handles.bin,20*log10(abs(handles.spectrum)));
		else
			imagesc(handles.t,handles.bin,abs(handles.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);
	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)+18 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

		
% --------------------------------------------------------------------

function [a,b] = designfilter(handles)
	order = str2double(get(handles.filtorder,'String'));
	contents = get(handles.filtermenu,'String');
	cut1 = str2double(get(handles.cut1,'String'));
	cut2 = str2double(get(handles.cut2,'String'));
	cut1 = cut1/(handles.Fs/2);
	cut2 = cut2/(handles.Fs/2);
	switch (lower(contents{get(handles.filtermenu,'Value')}))
		case 'allpass'
			b = 1;
		case 'lowpass'
			b = fir1(order, cut1, 'low');
		case 'highpass'
			b = fir1(order, cut1, 'high');
		case 'bandpass'
			b = fir1(order, [cut1 cut2], 'bandpass');
		case 'notch'
			b = fir1(order, [cut1 cut2], 'stop');
	end
	a = 1;


function ud = apply_filter(ud)
    polepos=findobj(ud.pz_plot,'Tag','Pole');
    zeropos=findobj(ud.pz_plot,'Tag','Zero');
    gain = str2num(get(ud.gain,'String'));
    len=max(length(polepos),length(zeropos));
    pp=zeros(1,len);  % pp=1e-10*rand(1,len);
    for p=1:length(polepos)
        ppos=get(polepos(p),'Position');
        pp(p)=ppos(1)+ppos(2)*i;
    end
    zz=zeros(1,len);  % zz=1e-10*rand(1,len);
    for z=1:length(zeropos)
        zp=get(zeropos(z),'Position');
        zz(z)=zp(1)+zp(2)*i;
    end
    ud.zz=zz;ud.pp=pp;
    [ud.num,ud.den]=zp2tf(zz',pp',1);
	ud.audiodata2 = ud.audiodata;
	ud.audiodata.data = gain*filter(ud.num, ud.den, ud.audiodata.data);
    if max(abs(ud.audiodata.data))>1
        ud.audiodata.data = normalize(ud.audiodata.data);
    end
	% Store old data for undo
	ud.spectrum2 = ud.spectrum;
	ud.bin2 = ud.bin;
	ud.st2 = ud.st;
	set(ud.undo,'String','Undo');


function handles = undo(handles)
	hObject = handles.undo;
	if (strcmp(get(hObject,'String'),'Undo'))
		% Store old data for redo
		handles.spectrum3 = handles.spectrum;
		handles.bin3 = handles.bin;
		handles.st3 = handles.st;
		handles.audiodata3 = handles.audiodata;
		% Reload old data
		handles.spectrum = handles.spectrum2;
		handles.bin = handles.bin2;
		handles.st = handles.st2;
		handles.audiodata = handles.audiodata2;
		set(hObject,'String','Redo');
	else
		handles.spectrum = handles.spectrum3;
		handles.bin = handles.bin3;
		handles.st = handles.st3;
		handles.audiodata = handles.audiodata3;
		set(hObject,'String','Undo');
	end

function ud = add_coef(ud,type)
	switch type
		case 'zero'
			string = 'o';
			callbak = 'pzfilterexpofn selectzero';
			tag = 'Zero';
		case 'pole'
			string = 'x';
			callbak = 'pzfilterexpofn selectpole';
			tag = 'Pole';
	end
	[x,y]=pol2cart(pi/(2+4*rand(1)),1.0*rand(1));
	p1=text('Parent',ud.pz_plot,'Position',[x y],'String',string,...
		'ButtonDownFcn',callbak,'EraseMode','xor',...
		'Tag',tag,'HorizontalAlignment','center');
	p2=text('Parent',ud.pz_plot,'Position',[x -y],'String',string,...
		'ButtonDownFcn',callbak, 'EraseMode','xor',...
		'Tag',tag,'HorizontalAlignment','center');
	set(p1,'UserData',p2);
	set(p2,'UserData',p1);

function ud = select_coef(ud,type)
	switch type
		case 'zero'
			buttonfn = 'pzfilterexpofn movezero';
		case 'pole'
			buttonfn = 'pzfilterexpofn movepole';
	end
	s=get(gcbo,'UserData');
	set(gcf,'WindowButtonMotionFcn', buttonfn);
	set(gcf,'WindowButtonUpFcn','pzfilterexpofn releaseobject');
	ud.currentcoef=gcbo;
	ud.partnercoef=s;
	set([findobj(gca,'Tag','Pole'); findobj(gca,'Tag','Zero')],'Selected','off');
	set([ud.currentcoef ud.partnercoef],'Selected','on');


function ud = move_coef(ud)
	cp=get(ud.pz_plot,'CurrentPoint');
	if (cp(1)*cp(1)+cp(3)*cp(3)) < 1.1
	  set(ud.currentcoef,'Position',[cp(1) cp(3)]);
	  set(ud.partnercoef,'Position',[cp(1) -cp(3)]);
	end