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