www.gusucode.com > 声音的处理有:LPC,FFT,共振峰,频谱源码程序 > siganlandsystemusingMatlab/SSUM/formant/formantexpofn.m
function formantexpofn(action,datastruct) if nargin < 1 action='init'; end % windowsize 64 doesn't work for 44100 % Load sound, play, load diff sound, change window size, no work % clean up freq labels for log freq and linear freq 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.dataplot); reset(handles.timeplot); case 'loadsound' handles.audiodata = load_audiodata; if ~isfield(handles.audiodata, 'filenamepath') return; end if (size(handles.audiodata.data,2) > 1) handles.audiodata.data = to_mono(handles.audiodata.data); end % rule of thumb for formant estimation handles.ncoeff=round(2+handles.audiodata.Fs/1000); handles = makeTimePlot(handles); handles = makeSpecPlot(handles); handles = makeDataPlot(handles); place_header(f, handles); set(handles.freqzoom,'Value',1); set(handles.ampzoom,'Value',0.5); case 'readinput' handles.audiodata = datastruct; clear datastruct; handles.audiodata.filenamepath = ''; handles.audiodata.nBits = 16; handles.audiodata; handles.audiodata.channels = size(handles.audiodata.data,2); handles.ncoeff=round(2+handles.audiodata.Fs/1000); handles = makeTimePlot(handles); handles = makeSpecPlot(handles); handles = makeDataPlot(handles); place_header(f, handles); set(handles.freqzoom,'Value',1); set(handles.ampzoom,'Value',0.5); case 'playsound' if isfield(handles, 'audiodata') audiodata = handles.audiodata; if (max(abs(audiodata.data)) > 1.0) audiodata.data = normalize(audiodata.data); end play_audiodata(audiodata, handles.play); end case 'logfreq' if (get(handles.logfreq,'Value')) set(handles.specplot,'XScale','log'); else set(handles.specplot,'XScale','linear'); end case {'db'} if isfield(handles, 'audiodata') updateSpecPlot(handles); if (get(handles.dB,'Value')) axes(handles.specplot) ylabel('Log Magnitude (dB)'); else axes(handles.specplot) ylabel('Amplitude'); end formantexpofn 'freqzoom'; formantexpofn 'ampzoom'; end case 'entire' if isfield(handles, 'audiodata') handles = makeSpecPlot(handles); handles = makeDataPlot(handles); formantexpofn 'freqzoom'; formantexpofn 'ampzoom'; end case 'stem' if isfield(handles, 'audiodata') handles = makeSpecPlot(handles); formantexpofn 'freqzoom'; formantexpofn 'ampzoom'; end case 'formanttype' if isfield(handles, 'audiodata') handles = makeSpecPlot(handles); formantexpofn 'freqzoom'; formantexpofn 'ampzoom'; end case 'dataplot' if isfield(handles, 'audiodata') handles = makeDataPlot(handles); end case {'fftsize','window','smoothfft'} if isfield(handles, 'audiodata') contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end wintime = fftsize/handles.audiodata.Fs; handles.right = handles.left + wintime; if handles.right > handles.maxtime handles.right = handles.maxtime; handles.left = handles.maxtime - wintime; end set(handles.l,'XData',[handles.left handles.left]); set(handles.r,'XData',[handles.right handles.right]); handles = makeSpecPlot(handles); handles = makeDataPlot(handles); formantexpofn 'freqzoom'; formantexpofn 'ampzoom'; end case 'normalize' if isfield(handles,'audiodata') handles.audiodata.data = normalize(handles.audiodata.data); handles = makeTimePlot(handles); handles = makeDataPlot(handles); handles = makeSpecPlot(handles); end % The following taken in large part from MAD. case 'left' set(gcf,'WindowButtonMotionFcn','formantexpofn moveleft'); set(gcf,'WindowButtonUpFcn','formantexpofn release'); case 'right' set(gcf,'WindowButtonMotionFcn','formantexpofn moveright'); set(gcf,'WindowButtonUpFcn','formantexpofn release'); case 'moveleft' handles = moveleft(handles); updateSpecPlot(handles); updateDataPlot(handles); case 'moveright' handles = moveright(handles); updateSpecPlot(handles); updateDataPlot(handles); case 'release' set(gcf,'WindowButtonMotionFcn',''); set(gcf,'WindowButtonUpFcn',''); case {'sonogram', 'alias'} if isfield(handles,'audiodata'), audiodata = handles.audiodata; switch action case 'sonogram' sonoexpogui(audiodata); case 'alias' aliasexpogui(audiodata); end end case 'freqzoom' if isfield(handles,'audiodata') val = get(handles.freqzoom,'Value'); if val == 0, val = 0.001; end Fs = handles.audiodata.Fs; if get(handles.entire,'Value') set(handles.specplot,'XLim',[-val*Fs/2 val*Fs/2]) else set(handles.specplot,'XLim',[0 val*Fs/2]) end end case 'ampzoom' if isfield(handles,'audiodata') val = get(handles.ampzoom,'Value'); if val == 0, val = 0.001; end if get(handles.dB,'Value'), set(handles.specplot,'YLim',[-100 (2*val*100-40)]) else set(handles.specplot,'YLim',[0 val*200]) 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); contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end axes(handles.timeplot); cla; handles.t = [0:1/handles.audiodata.Fs:(length(handles.audiodata.data)-1)/... handles.audiodata.Fs]; maxtime = length(handles.t)/handles.audiodata.Fs; handles.maxtime = maxtime; handles.winleft = 0; handles.winright = maxtime; if max(handles.audiodata.data) > 1 handles.audiodata.data = normalize(handles.audiodata.data); end plot(handles.t,handles.audiodata.data) xlabel('time (s)'); set(handles.timeplot,'NextPlot','replacechildren','Drawmode','fast',... 'XLim',[0 maxtime], 'YLim', [-1.1 1.1]); grid on; hold on; handles.left = 0.1*maxtime; handles.delta = fftsize/handles.audiodata.Fs; handles.right = handles.left + handles.delta; handles.l=line([handles.left handles.left],get(gca,'YLim'),'Color','r',... 'ButtonDownFcn','formantexpofn left','LineWidth', 2,'EraseMode','xor'); handles.r=line([handles.right handles.right],get(gca,'YLim'),'Color','r',... 'ButtonDownFcn','formantexpofn right','LineWidth', 2,'EraseMode','xor'); handles.step=0.2*maxtime; function handles = makeDataPlot(handles); contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end contents = get(handles.Window,'String'); shape = contents{get(handles.Window,'Value')}; % Get x-position of samples startpos = floor(handles.left*handles.audiodata.Fs+1); signal = handles.audiodata.data(startpos:startpos+fftsize-1); contents = get(handles.datamenu,'String'); axes(handles.dataplot); switch lower(contents{get(handles.datamenu,'Value')}) case 'autocorrelation' %data = conv(signal,fliplr(signal)); data = xcorr(signal); t = [0:length(data)-1]./handles.audiodata.Fs; handles.dataline = plot(t,data); set(handles.dataplot, 'XLim',[max(t)/2 max(t)]); case 'cepstrum' signal = signal.*get_windowdata(fftsize, shape); fftsignal = fft(signal); data = ifft(log10(abs(fftsignal))); data = real(data); t = [0:length(data)-1]./handles.audiodata.Fs; handles.dataline = plot(t,data); set(handles.dataplot, 'XLim',[0 max(t)/2]); end set(handles.dataline, 'EraseMode','background'); set(handles.dataplot, 'YLimMode','auto',... 'NextPlot','replacechildren','Drawmode','fast'); xlabel('Time (s)'); axis xy; grid on; function handles = makeSpecPlot(handles); contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end contents = get(handles.Window,'String'); shape = contents{get(handles.Window,'Value')}; axes(handles.specplot); % Get x-position of samples startpos = floor(handles.left*handles.audiodata.Fs+1); signal = handles.audiodata.data(startpos:startpos+fftsize-1).*... get_windowdata(fftsize, shape); fftsignal = fft(signal); f = fftshift(fftsignal); if (get(handles.dB,'Value')) f = 20*log10(1e-10+abs(f)); else f = abs(f); end freqs = linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,fftsize); if (get(handles.smoothfft,'Value')) f=interp1(linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2, ... length(f)),f,freqs); end if get(handles.stem,'Value') handles.sp = stem(freqs,f); else handles.sp = plot(freqs,f); end if get(handles.entire,'Value') set(handles.specplot, ... 'XLim',[-handles.audiodata.Fs/2 handles.audiodata.Fs/2], ... 'YLim',[-100 60]); else set(handles.specplot,'XLim',[0 handles.audiodata.Fs/2], ... 'YLim',[-100 60]); end if (get(handles.logfreq,'Value')) set(handles.specplot,'XScale','log'); else set(handles.specplot,'XScale','linear'); end axis xy; grid; ylabel('Log Magnitude (dB)'); set(handles.sp, 'EraseMode','background','LineWidth',1); xlabel('Frequency (kHz)'); % Now find and plot formant a=lpc(signal,handles.ncoeff); switch lower(get(handles.formanttype,'String')) case 'formant' [h,f]=freqz(1,a,512,handles.audiodata.Fs); case 'anti-formant' [h,f]=freqz(a,1,512,handles.audiodata.Fs); end axes(handles.specplot); hold on; handles.formant = plot(f,20*log10(abs(h))); set(handles.formant,'LineStyle','--','LineWidth',3,... 'Color','g','EraseMode','background'); % Take fist 2 ms of ceps %ceps = ceps(1:ceil(handles.audiodata.Fs*0.003)); %% Find Fourier transform of this data %windowdata = get_windowdata(length(ceps),'hann'); %ceps = windowdata.*ceps; %cepsfft = fftshift(fft(ceps)); %% Now plot mag %cepsfft = resample(cepsfft,8,1); %freqs = linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,length(cepsfft)); %plot(freqs,20*log10(abs(cepsfft))); hold off; % -------------------------------------------------------------------- function updateTimePlot(handles) axes(handles.timeplot) plot(handles.t,handles.audiodata) xlabel('time (s)'); grid on; function updateDataPlot(handles) contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end contents = get(handles.Window,'String'); shape = contents{get(handles.Window,'Value')}; % Get x-position of samples startpos = floor(handles.left*handles.audiodata.Fs+1); signal = handles.audiodata.data(startpos:startpos+fftsize-1); contents = get(handles.datamenu,'String'); switch lower(contents{get(handles.datamenu,'Value')}) case 'autocorrelation' data = xcorr(signal); case 'cepstrum' signal = signal.*get_windowdata(fftsize, shape); fftsignal = fft(signal); data = ifft(log10(abs(fftsignal))); data = real(data); end set(handles.dataline,'YData',data); ylims = get(handles.dataplot,'YLim'); if ylims(1) > 0.9*min(data) | ylims(2) < 1.1*max(data) set(handles.dataplot,'YLim',[min(data) max(data)]); end function updateSpecPlot(handles) contents = get(handles.fftsize,'String'); fftsize = contents{get(handles.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(handles.audiodata.data); else fftsize = str2num(fftsize); end contents = get(handles.Window,'String'); shape = contents{get(handles.Window,'Value')}; % Get x-position of samples startpos = floor(handles.left*handles.audiodata.Fs+1); signal = handles.audiodata.data(startpos:startpos+fftsize-1).*... get_windowdata(fftsize, shape); fftsignal = fft(signal); f = fftshift(fftsignal); if (get(handles.dB,'Value')) f = 20*log10(1e-10+abs(f)); else f = abs(f); end freqs = linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,fftsize); if (get(handles.smoothfft,'Value')) f=interp1(linspace(-handles.audiodata.Fs/2,handles.audiodata.Fs/2,length(f)),f,freqs); end %if (get(handles.logfreq,'Value')) % set(handles.specplot,'XScale','log'); %else % set(handles.specplot,'XScale','linear'); %end if get(handles.stem,'Value') set(handles.sp(1),'YData',f); temp = get(handles.sp(2),'YData'); temp(2:3:end) = f; set(handles.sp(2),'YData',temp); else set(handles.sp, 'YData', f); end a=lpc(signal,handles.ncoeff); switch lower(get(handles.formanttype,'String')) case 'formant' [h,f]=freqz(1,a,512,handles.audiodata.Fs); case 'anti-formant' [h,f]=freqz(a,1,512,handles.audiodata.Fs); end set(handles.formant,'YData', 20*log10(abs(h))); % -------------------------------------------------------------------- function ud = moveleft(ud) contents = get(ud.fftsize,'String'); fftsize = contents{get(ud.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(ud.audiodata.data); else fftsize = str2num(fftsize); end currentPoint=get(gca,'CurrentPoint'); ud.left=currentPoint(1); wintime = fftsize/ud.audiodata.Fs; if ud.left <= ud.winleft ud.left=0; end if ud.left >= (ud.winright-wintime) ud.left=ud.winright-wintime; end set(ud.l,'XData',[ud.left ud.left]); set(ud.r,'XData',[ud.left+wintime ud.left+wintime]); function ud = moveright(ud) contents = get(ud.fftsize,'String'); fftsize = contents{get(ud.fftsize,'Value')}; if strncmp(fftsize,'Entire',6) fftsize = length(ud.audiodata.data); else fftsize = str2num(fftsize); end currentPoint=get(gca,'CurrentPoint'); ud.right=currentPoint(1); wintime = fftsize/ud.audiodata.Fs; if ud.right <= (ud.winleft+wintime) ud.right=wintime; end if ud.right >= (ud.winright) ud.right=ud.winright; end ud.left = ud.right - wintime; set(ud.r,'XData',[ud.right ud.right]); set(ud.l,'XData',[ud.right-wintime ud.right-wintime]);