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

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

	% Analysis size text entry
	% Synthesis window, size, skip parameters
	% Option to apply specific amplitude envelope to synthesis
	%	such as RMS of original
	% Options to substitute particular bins

	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.timeplot1);
			reset(handles.timeplot2);
			linkedzoom([handles.timeplot1,handles.timeplot2],'onxy');
			cola_check(handles);
		case 'loadsound'
			audiodata = load_audiodata;
            if isempty(audiodata)
                return
            end
			if (max(abs(audiodata.data)) > 1.0)
				audiodata.data = normalize(audiodata.data);
			end
			handles.audiodata = audiodata;
			makeTimePlot(handles.audiodata, handles.timeplot1);
			place_header(f,handles);
		case 'readinput'
            setdefaults;
			reset(handles.timeplot1);
			reset(handles.timeplot2);
			place_header(f,handles);
		case 'analyze'
			if isfield(handles,'audiodata')
				windowsize = str2double(get(handles.analwindowsize,'String'));
				windowskip = str2double(get(handles.analwindowskip,'String'));
				windowshapecontents = get(handles.analwindowshape,'String');
				windowshape = windowshapecontents{get(handles.analwindowshape,'Value')};
				handles.analysisdata = analyze(handles.audiodata, windowsize, ...
						windowskip, windowshape);
			end
		case 'synthesize'
			if isfield(handles,'analysisdata')
				windowsize = str2double(get(handles.synthwindowsize,'String'));
				windowskip = str2double(get(handles.synthwindowskip,'String'));
				windowshapecontents = get(handles.analwindowshape,'String');
				windowshape = windowshapecontents{get(handles.analwindowshape,'Value')};
				magcontents = get(handles.magmenu,'String');
				magoption = magcontents{get(handles.magmenu,'Value')};
				phasecontents = get(handles.phasemenu,'String');
				phaseoption = phasecontents{get(handles.phasemenu,'Value')};
				handles.synthdata = synthesize(handles.analysisdata, ...
					windowsize, windowskip, windowshape, magoption, phaseoption);
				%if length(handles.synthdata.data) > length(handles.audiodata.data)
				%	handles.synthdata.data = ...
				%		handles.synthdata.data(1:length(handles.audiodata.data),:);
				%end
				if (max(abs(handles.synthdata.data)) > 1.0)
					handles.synthdata.data = normalize(handles.synthdata.data);
				end
				makeTimePlot(handles.synthdata, handles.timeplot2);
			end
		case 'normalize'
             if isfield(handles,'synthdata')
                 handles.synthdata.data = normalize(handles.synthdata.data);
                 xlim = get(handles.timeplot1,'XLim');
                 makeTimePlot(handles.synthdata, handles.timeplot2);
                 set(handles.timeplot2,'XLim',xlim);
             end
		case {'playsound1','playsound2'}
                audiodata = {};
                times = get(handles.timeplot1,'XLim');
                switch action
                    case 'playsound1'
                        if isfield(handles,'audiodata')
                            audiodata = handles.audiodata;
                            playbutton = handles.play1;
                        end
                    otherwise
                        if isfield(handles,'synthdata')
                            audiodata = handles.synthdata;
                            playbutton = handles.play2;
                        end
                end
                if ~isempty(audiodata)
                    samples = round(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));
                    play_audiodata(audiodata, playbutton);
                end
        case {'orig_fourier','orig_sonogram'}
			if isfield(handles,'audiodata'),
                audiodata = handles.audiodata;
				if size(audiodata.data,2) > 1
					audiodata.data = to_mono(audiodata.data);
				end
                switch action
                    case 'orig_fourier'
						fourierexpogui(audiodata);
                    case 'orig_sonogram'
                        sonoexpogui(audiodata);
                end
            end
		case {'synth_fourier','synth_sonogram'}
			if isfield(handles,'synthdata'),
                audiodata = handles.synthdata;
				if size(audiodata.data,2) > 1
					audiodata.data = to_mono(audiodata.data);
				end
                switch action
                    case 'synth_fourier'
						fourierexpogui(audiodata);
                    case 'synth_sonogram'
                        sonoexpogui(audiodata);
                end
            end
		case 'saveresynth'
			if isfield(handles, 'synthdata')
				save_audiodata(handles.synthdata);
			end
		case 'colacheck'
			cola_check(handles);
		case 'print'
			print_figure(f);
		case 'close'
			close_figure(f,figname(1:end-4));
            return;
	end
	set(f,'UserData',handles);


function makeTimePlot(audiodata, axesnum);
	if max(max(audiodata.data)) > 1
		audiodata.data = normalize(audiodata.data);
	end
	axes(axesnum)
	t = [0:1/audiodata.Fs:(length(audiodata.data)-1)/audiodata.Fs];

	plot(t,audiodata.data)
	maxtime = length(t)/audiodata.Fs;
	set(axesnum,'XLim',[0 maxtime]);
	set(axesnum,'YLim',[-1.0 1.0]);
	grid;
	xlabel('time (s)');


% --------------------------------------------------------------------
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 analysis = analyze(audiodata, windowsize, windowskip, windowshape);
	% Perform COLA analysis of audiodata
	analysis.Fs = audiodata.Fs;
	analysis.windowsize = windowsize;
	analysis.windowskip = windowskip;
	analysis.windowshape = windowshape;
	windowdata = get_windowdata(windowsize,windowshape);
	%switch lower(windowshape),
	%	case {'hann', 'triangle'}
	%		windowskip = floor(windowsize/2);
	%	case 'rectangle'
	%		windowskip = windowsize;
	%end
	num_channels = min(size(audiodata.data));
	num_windows = floor(length(audiodata.data)/windowskip);
	if (num_windows+1)*windowskip+(windowsize-windowskip) > length(audiodata.data)
		audiodata.data = [audiodata.data; ...
			zeros(((num_windows+1)*windowskip+(windowsize-windowskip) - ...
				length(audiodata.data)),num_channels)];
	end

	h = waitbar(0, 'Analyzing ...');
	for i=1:num_windows,
		for k = 1:min(size(audiodata.data))
			start_sample = (i-1)*windowskip + 1;
			end_sample = start_sample + windowsize-1;	
			frame = audiodata.data(start_sample:end_sample,k);
			frame = frame.*windowdata;
			analysis.data{i,k} = fft(frame);
		end
		waitbar(i/num_windows,h);
	end
	close(h);

% --------------------------------------------------------------------
function synthesis = synthesize(analysis, windowsize, windowskip, windowshape, magoption, phaseoption);
	synthesis.Fs = analysis.Fs;
	%switch lower(windowshape),
	%	case {'hann', 'triangle'}
	%		windowskip = floor(windowsize/2);
	%	case 'rectangle'
	%		windowskip = windowsize;
	%end

	num_channels = min(size(analysis.data));
	num_windows = length(analysis.data);
	synthesis.data = zeros((num_windows+1)*windowskip+(windowsize-windowskip),num_channels);
	windowdata = ones(windowsize,1);
	if analysis.windowsize ~= windowsize
		windowdata = get_windowdata(windowsize,windowshape);
	end

	switch lower(magoption)
		case 'random'
			for i=1:num_windows
				for k = 1:num_channels
					amp = rand(windowsize,1);
					phase = angle(analysis.data{i,k});
					analysis.data{i,k} = complex(amp.*cos(phase),amp.*sin(phase));
				end
			end
			windowdata = (get_windowdata(windowsize,windowshape)).^2;
		case 'other'
			% Load soundfile and get its magnitude information
			audiodata = load_audiodata;
            if ~isempty(audiodata)
				if size(audiodata.data,2) > 1,
					audiodata.data = to_mono(audiodata.data);
				end
				analysis2 = analyze(audiodata, analysis.windowsize, analysis.windowskip, windowshape);
				for i=1:num_windows
					for k = 1:num_channels
						amp = abs(analysis2.data{mod(i-1,length(analysis2.data))+1});
						phase = angle(analysis.data{i,k});
						analysis.data{i,k} = complex(amp.*cos(phase), amp.*sin(phase));
					end
				end
			end
			windowdata = get_windowdata(windowsize,windowshape);
	end

	switch lower(phaseoption)
		case 'random'
			for i=1:num_windows
				for k = 1:num_channels
					amp = abs(analysis.data{i,k});
					phase = pi*rand(analysis.windowsize,1);
					analysis.data{i,k} = complex(amp.*cos(phase), amp.*sin(phase));
				end
			end
			windowdata = (get_windowdata(windowsize,windowshape)).^2;
		case 'zero'
			phaseamt = pi*rand;
			for i=1:num_windows
				for k = 1:num_channels
					amp = abs(analysis.data{i,k});
					phase = phaseamt*ones(analysis.windowsize,1);
					analysis.data{i,k} = complex(amp.*cos(phase), amp.*sin(phase));
				end
			end
			windowdata = get_windowdata(windowsize,windowshape).^2;
		case 'other'
			% Load soundfile and get its phase information
			audiodata = load_audiodata;
            if ~isempty(audiodata)
				if size(audiodata.data,2) > 1,
					audiodata.data = to_mono(audiodata.data);
				end
				analysis2 = analyze(audiodata, analysis.windowsize, analysis.windowskip, windowshape);
				for i=1:num_windows
					for k = 1:num_channels
						amp = abs(analysis.data{i,k});
						phase = angle(analysis2.data{mod(i-1,length(analysis2.data))+1});
						analysis.data{i,k} = complex(amp.*cos(phase), amp.*sin(phase));
					end
				end
			end
			windowdata = get_windowdata(windowsize,windowshape);
	end
	h = waitbar(0, 'Synthesizing ...');
	for i=1:num_windows
		for k=1:num_channels
			start_sample = (i-1)*windowskip + 1;
			end_sample = start_sample + windowsize-1;
			sig = real(ifft(analysis.data{i,k}));
			while length(sig) < windowsize
				sig = [sig; sig];
			end
			synthesis.data(start_sample:end_sample,k) = ...
				synthesis.data(start_sample:end_sample,k) + ...
					windowdata.*sig(1:windowsize);
		end
		waitbar(i/num_windows,h);
	end
	close(h);

function cola_check(handles)
	if get(handles.analcola,'Value')
		winsize = str2double(get(handles.analwindowsize,'String'));
		% if windowshape = ...
		set(handles.analwindowskip,'String',num2str(ceil(winsize/2)));
		set(handles.analwindowskip,'Enable','inactive');
	else
		set(handles.analwindowskip,'Enable','on');
	end

	if get(handles.synthcola,'Value')
		winsize = str2double(get(handles.synthwindowsize,'String'));
		set(handles.synthwindowskip,'String',num2str(ceil(winsize/2)));
		set(handles.synthwindowskip,'Enable','inactive');
	else
		set(handles.synthwindowskip,'Enable','on');
	end