www.gusucode.com > 声音的处理有:LPC,FFT,共振峰,频谱源码程序 > siganlandsystemusingMatlab/SSUM/feature/featurexpofn.m
function featurexpofn(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; reset(handles.specplot); reset(handles.featureplot1); reset(handles.featureplot2); case 'loadsound' audiodata = load_audiodata; if isempty(audiodata) return end handles.fileopen = true; handles.channels = size(audiodata.data,2); if size(audiodata.data,2) > 1, audiodata.data = to_mono(audiodata.data); end handles.audiodata = audiodata; handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/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); set(handles.freqzoom,'Value',1.0); handles = makeSpecPlot(handles); handles.featuretype = {{'zero'}, {'rms'}, {'spec_centroid'}, ... {'spec_rolloff'}, {'harmonicity'}, {'pitch'}}; handles.featuredata = {}; handles = makeFeatureData(handles); handles = drawFeaturePlot(handles,1); handles = drawFeaturePlot(handles,2); timeticks = max(handles.ftimes); set(handles.specplot,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks], 'XTickLabel', ''); set(handles.featureplot1,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks], 'XTickLabel', ''); set(handles.featureplot2,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks]); axes(handles.featureplot2); xlabel('Time (s)'); linkedzoom([handles.specplot, handles.featureplot1, handles.featureplot2],'onx'); place_header(f,handles); featurexpofn 'freqzoom'; case 'readinput' % This will read in analysis data and load accompanying sound setdefaults; reset(handles.specplot); reset(handles.featureplot1); reset(handles.featureplot2); audiodata = datastruct; clear datastruct; handles.fileopen = true; if size(audiodata.data,2) > 1, audiodata.data = to_mono(audiodata.data); end handles.audiodata = audiodata; handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/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); set(handles.freqzoom,'Value',1.0); handles = makeSpecPlot(handles); handles.featuretype = {{'zero'}, {'rms'}, {'spec_centroid'}, ... {'spec_rolloff'}, {'harmonicity'}, {'pitch'}}; handles.featuredata = {}; handles = makeFeatureData(handles); handles = drawFeaturePlot(handles,1); handles = drawFeaturePlot(handles,2); timeticks = max(handles.ftimes); set(handles.specplot,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks], 'XTickLabel', ''); set(handles.featureplot1,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks], 'XTickLabel', ''); set(handles.featureplot2,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 timeticks]); axes(handles.featureplot2); xlabel('Time (s)'); linkedzoom([handles.specplot, handles.featureplot1, handles.featureplot2],'onx'); place_header(f,handles); featurexpofn 'freqzoom'; case 'playsound' if isfield(handles,'audiodata'), times = get(handles.featureplot1,'XLim'); audiodata = handles.audiodata; 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, handles.play); end case {'db','inverse','interpolate','colormap'} if isfield(handles,'audiodata'), xlim = get(handles.specplot,'XLim'); updateSpecPlot(handles); set(handles.specplot,'XLim',xlim); featurexpofn '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); xlim = get(handles.specplot,'XLim'); updateSpecPlot(handles); featurexpofn 'freqzoom'; handles.featuredata = {}; handles = makeFeatureData(handles); handles = drawFeaturePlot(handles,1); handles = drawFeaturePlot(handles,2); timeticks = max(handles.ftimes); set(handles.specplot,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim, 'XTickLabel', ''); set(handles.featureplot1,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim, 'XTickLabel', ''); set(handles.featureplot2,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim); axes(handles.featureplot2); xlabel('Time (s)'); end case {'feature1_update','feature2_update'} switch action case 'feature1_update' plotnum = 1; case 'feature2_update' plotnum = 2; end handles = drawFeaturePlot(handles, plotnum); timeticks = max(handles.ftimes); xlim = get(handles.specplot,'XLim'); set(handles.specplot,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim, 'XTickLabel', ''); set(handles.featureplot1,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim, 'XTickLabel', ''); set(handles.featureplot2,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',xlim); axes(handles.featureplot2); xlabel('Time (s)'); 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') timeticks = max(handles.ftimes); set(handles.specplot,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 max(timeticks)], 'XTickLabel', ''); set(handles.featureplot1,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 max(timeticks)], 'XTickLabel', ''); set(handles.featureplot2,'XTick',[0:timeticks*0.1:timeticks], ... 'XLim',[0 max(timeticks)]); end case {'fourier', 'alias', 'sonogram', 'firfilter', 'pzfilter','sws'} if isfield(handles,'audiodata'), audiodata = handles.audiodata; switch action case 'fourier' fourierexpogui(audiodata); case 'alias' aliasexpogui(audiodata); case 'sonogram' sonoexpogui(audiodata); case 'firfilter' firexpogui(audiodata); case 'pzfilter' pzfilterexpogui(audiodata); case 'sws' swsexpogui(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 = drawFeaturePlot(handles, plotnum); switch plotnum case 1 contents = get(handles.feature1,'String'); feature = contents{get(handles.feature1,'Value')}; axes(handles.featureplot1); case 2 contents = get(handles.feature2,'String'); feature = contents{get(handles.feature2,'Value')}; axes(handles.featureplot2); end contents = get(handles.fftsize,'String'); window_size = str2double(contents{get(handles.fftsize,'Value')}); contents = get(handles.window,'String'); shape = contents{get(handles.window,'Value')}; windowdata = get_windowdata(window_size,shape); num_samples = size(handles.audiodata.data,1); % What if window_skip used in outside analysis isn't cola? window_skip = window_size/2; % COLA num_windows = floor(num_samples/window_skip)-1; handles.ftimes = (1:length(handles.featuredata))*window_skip/handles.audiodata.Fs; switch (lower(feature)) case 'zero crossings' fstring = 'zero'; ylabel('Zero Crossings'); case 'rms' fstring = 'rms'; ylabel('RMS'); case 'spectral centroid' fstring = 'spec_centroid'; ylabel('Spectral Centroid (Hz)'); case 'spectral rolloff' fstring = 'spec_rolloff'; ylabel('Spectral Rolloff'); case 'harmonicity' fstring = 'harmonicity'; ylabel('Harmonicity'); case 'pitch' fstring = 'pitch'; ylabel('Pitch (Hz)'); case 'time series' ylabel('Amplitude'); plot(handles.t,handles.audiodata.data); set(gca,'XLim',[0 max(handles.t)]); set(gca,'YLim',[-1.1 1.1]); grid; return; end col = find(strcmp([handles.featuretype{:}],fstring)); data = [handles.featuredata{:,col}]; stairs(handles.ftimes,data); grid; function handles = makeSpecPlot(handles); axes(handles.specplot); handles.pos = get(gca,'Position'); % Save axes position if (get(handles.dB,'Value')) imagesc(handles.t,handles.bin,20*log10(abs(handles.spectrum))); else imagesc(handles.t,handles.bin,abs(handles.spectrum)); end %shading interp; axis xy; ylabel('Frequency (Hz)'); colormap('Jet'); set(handles.specplot,'XTickLabel',['']); h = colorbar('vert'); if (get(handles.dB,'Value')) set(get(h, 'YLabel'), 'String', 'dB'); else set(get(h, 'YLabel'), 'String', 'Amplitude'); end set(h,'Position',[0.7 0.6162 0.0404327 0.3651]) 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 updateSpecPlot(handles) axes(handles.specplot); % Check Interpolate and dB if (get(handles.interpolate,'Value')) if (get(handles.dB,'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.dB,'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 h = colorbar('vert'); if (get(handles.dB,'Value')) set(get(h, 'YLabel'), 'String', 'dB'); else set(get(h, 'YLabel'), 'String', 'Amplitude'); end set(h,'Position',[0.7 0.6162 0.0404327 0.3651]) 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 = makeFeatureData(handles); contents = get(handles.fftsize,'String'); window_size = str2double(contents{get(handles.fftsize,'Value')}); contents = get(handles.window,'String'); shape = contents{get(handles.window,'Value')}; windowdata = get_windowdata(window_size,shape); num_samples = size(handles.audiodata.data,1); window_skip = window_size/2; % COLA num_windows = floor(num_samples/window_skip)-1; Fs = handles.audiodata.Fs; [b,a] = butter(10, 900/(Fs/2)); % Calculate all datatypes if necessary if (isempty(handles.featuredata) | handles.feature_window_size ~= window_size) h = waitbar(0,'Analyzing'); for i = 1:num_windows, start_sample = (i-1)*window_skip + 1; end_sample = start_sample + window_size-1; frame = handles.audiodata.data(start_sample:end_sample).*windowdata; for j = 1:length(handles.featuretype), switch (lower(char(handles.featuretype{j}))) case 'zero' handles.featuredata{i,j} = zero_crossings(frame); case 'rms' handles.featuredata{i,j} = rms(frame); case 'spec_centroid' handles.featuredata{i,j} = spec_centroid(frame,Fs); case 'spec_rolloff' handles.featuredata{i,j} = spec_rolloff(frame,Fs); case 'harmonicity' handles.featuredata{i,j} = 0; case 'pitch' % low-pass filter frame < 900 Hz frame = filter(b,a,frame); handles.featuredata{i,j} = pitch1(frame, Fs); end end waitbar(i/num_windows,h); end close(h); handles.feature_window_size = window_size; end