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

    %
function denoisefn(action, datastruct)

    if nargin < 1
        action='init';
    end

	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;
            movegui(f,'center');
			reset(handles.timeplot);
			reset(handles.specplot);
        case 'resize'
            movegui(f,'onscreen');
		case 'loadsound'
			handles.audiodata = load_audiodata;
			handles.audiodata2 = 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
			set(handles.freqzoom,'Value',1.0);
			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);
			linkedzoom([handles.timeplot, handles.specplot],'onx');
			place_header(f,handles);
		case 'readinput'
			handles.audiodata = datastruct;
			clear datastruct;
			handles.audiodata.filenamepath = '';
			handles.audiodata.nBits = 16;
			handles.audiodata.channels = size(handles.audiodata.data,2);
			handles.audiodata2 = 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);
			linkedzoom([handles.timeplot, handles.specplot],'onx');
			place_header(f,handles);
		case {'playsound', 'playoriginal'}
			if isfield(handles,'audiodata'),
				times = get(handles.timeplot,'XLim');
				switch action
                    case 'playsound'
                        audiodata = handles.audiodata;
                        button = handles.play;
                    case 'playoriginal'
                        audiodata = handles.audiodata2;
                        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 'doFilter'
            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);
                denoisefn 'freqzoom';
            end
		case {'undoFilter', 'undoNoise'}
			if isfield(handles,'audiodata')
				switch action
					case 'undoFilter'
						handles = undo(handles,'filter');
					case 'undoNoise'
						handles = undo(handles,'noise');
				end
                updateSpecPlot(handles);
                Xlim = get(handles.timeplot,'XLim');
                handles = makeTimePlot(handles);
                set(handles.specplot,'XLim',Xlim);
                set(handles.timeplot,'XLim',Xlim);
                denoisefn 'freqzoom';
            end
		case 'doNoise'
            if isfield(handles, 'audiodata')
                handles = apply_noise(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);
                denoisefn 'freqzoom';
            end
		case {'db','inverse','interpolate','colormap'}
			if isfield(handles,'audiodata')
				updateSpecPlot(handles);
                set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                denoisefn '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.spectrum, handles.bin, handles.st] = ...
					spectrogram(handles.audiodata, fftsize, shape);
				updateSpecPlot(handles);
				set(handles.specplot,'XLim',get(handles.timeplot,'XLim'));
                denoisefn '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 'normalize'
			if isfield(handles,'audiodata')
				handles.audiodata.data = normalize(handles.audiodata.data);
				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'));
				updateTimePlot(handles);
                set(handles.timeplot,'XLim',get(handles.specplot,'XLim'));
				linkedzoom([handles.timeplot, handles.specplot],'onx');
                denoisefn '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 {'fourier', 'alias', 'feature', 'firexpo', 'iirexpo', 'formantexpo', 'lpcexpo'}
            if isfield(handles,'audiodata'),
                audiodata = handles.audiodata;
			    switch action
				    case 'fourier'
				        fourierexpogui(audiodata);
                    case 'alias'
                        aliasexpogui(audiodata);
                    case 'feature'
                        featurexpogui(audiodata);
                    case 'firexpo'
                        firexpogui(audiodata);
                    case 'iirexpo'
                        iirexpogui(audiodata);
                    case 'formantexpo'
                        formantexpogui(audiodata);
                    case 'lpcexpo'
						lpcexpogui(audiodata);
			    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);
	axes(handles.timeplot);
	handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/...
		handles.audiodata.Fs];
	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;


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

function updateSpecPlot(handles)
	axes(handles.specplot);
	% Check Interpolate and dB
	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);

	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 handles = undo(handles,type)
	switch type
		case 'filter'
    		hObject = handles.undoFilter;
		case 'noise'
    		hObject = handles.undoNoise;
	end
    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 handles = apply_filter(handles)
	contents = get(handles.filtermenu,'String');
	order = str2num(get(handles.filterorder,'String'));
	% Store old data for undo
	handles.audiodata2 = handles.audiodata;
	handles.spectrum2 = handles.spectrum;
	handles.bin2 = handles.bin;
	handles.st2 = handles.st;
	switch(contents{get(handles.filtermenu,'Value')})
		case 'Moving Average'
			b_k = ones(1,order)./order;
			a = 1;
			handles.audiodata.data = filter(b_k, a, handles.audiodata.data);
		case 'Median'
			% Adapted from http://www.mathworks.nl/matlabcentral/fileexchange/loadFile.do?objectId=1230&objectType=file
			[r,c] = size(handles.audiodata.data);
			y = zeros(r,1);
			% pad ends
			if mod(order,2)==0
				l = order/2;
				x1 = [ones(l-1,1)*handles.audiodata.data(1); handles.audiodata.data;
					ones(l+1,1)*handles.audiodata.data(end)];
				x2 = [ones(l,1)*handles.audiodata.data(1); 
				handles.audiodata.data; ones(l,1)*handles.audiodata.data(end)];
			else
				l = (order-1)/2;
				x1 = [ones(l,1)*handles.audiodata.data(1); handles.audiodata.data;
                    ones(l+1,1)*handles.audiodata.data(end)];
			end

			h = waitbar(0,'Filtering');
			for k=1:r,
				y(k,1) = median(x1(k:k+order-1));
				waitbar(k/r,h);
			end
			close(h);

			if mod(order,2)==0
				h = waitbar(0,'Filtering');
				y1 = zeros(r,1);
				for k=1:len
					y1(k,1) = median(x2(k:k+order-1));
					waitbar(k/r,h);
				end
				close(h);
				y=(y+y1)/2;
			end
			handles.audiodata.data = y;
	end
	set(handles.undoFilter,'String','Undo');


function handles = apply_noise(handles)
	handles.audiodata2 = handles.audiodata;
	handles.spectrum2 = handles.spectrum;
    handles.bin2 = handles.bin;
    handles.st2 = handles.st;
	amp = str2double(get(handles.noiseAmplitude,'String'));
	contents = get(handles.noisemenu,'String');
	switch contents{get(handles.noisemenu,'Value')}
		case 'Cracks & Pops'
			% Add impulses and sincs
			dur = length(handles.audiodata.data)/handles.audiodata.Fs;
			% 5 per second average
			numticks = floor(dur*5);
			for i=1:numticks,
				clicktime = dur*rand;
				samplenum = floor(clicktime*handles.audiodata.Fs+1);
				if (rand < 0.2)
	   			% impulse
					handles.audiodata.data(samplenum) = handles.audiodata.data(samplenum) + amp;
				else
					clicklength = floor(handles.audiodata.Fs*rand/10);
					if (samplenum+clicklength) > (dur*handles.audiodata.Fs),
						samplenum = samplenum - clicklength;
					end
					n = [0:clicklength-1];
					sincw = sin(2*pi*0.1*n)./(n-floor(clicklength/2));
					sincw(find(sincw<-10)) = -1;
					sincw(find(sincw>10)) = 1;
					handles.audiodata.data(samplenum:(samplenum+clicklength-1)) = handles.audiodata.data(samplenum:(samplenum+clicklength-1)) + amp*sincw';
				end
			end
		case 'White Noise'
			handles.audiodata.data = handles.audiodata.data + amp*(rand(length(handles.audiodata.data),1)-0.5);
		case 'Gaussian'
			handles.audiodata.data = handles.audiodata.data + amp*(randn(length(handles.audiodata.data),1));
	end
    set(handles.undoNoise,'String','Undo');