www.gusucode.com > 声音的处理有:LPC,FFT,共振峰,频谱源码程序 > siganlandsystemusingMatlab/SSUM/stocho/stochofn.m
function stochofn(action) if nargin < 1 action='init'; end % Modularize % Percent overlap working? % Add composing in progress dialog 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' % Load in image data [x, cmap] = imread('stocho_gradient.jpg'); h_axis=axes('pos',[0 0 1 1]); image(x); colormap(cmap); set(h_axis,'TickDir', 'out') % Strange hack set(handles.s1_vol,'BackgroundColor',get(handles.s1_start,'BackgroundColor')) handles.Fs = 44100; setdefaults; case 'compose' section = handles.section; signal = synthesize(handles,section); eval(['handles.signal_' num2str(section) ' = signal;']); eval(['set(handles.s' num2str(section) '_mix,''Value'',1);']); set(f,'UserData',handles); stochofn 'plot' case 'play' if (handles.section == 0) handles.signal_0 = mixsections(handles); end playsound(handles); case 'spectrum' if (handles.section == 0) handles.signal_0 = mixsections(handles); end specsound(handles); case 'plot' if (handles.section == 0) handles.signal_0 = mixsections(handles); end plotsound(handles); case 'load_settings' handles = load_settings(handles); case 'save_settings' save_settings(handles); case 'write_soundfile' write_soundfile(handles); case 'vol_edit' section = handles.section; eval(['val = str2double(get(handles.s' num2str(section) '_vol,''String''));']); if (val > 1) eval(['set(handles.s' num2str(section) '_vol,''String'',''1.0'');']); val = 1; elseif (val < 0) eval(['set(handles.s' num2str(section) '_vol,''String'',''0.0'');']); val = 0; end eval(['set(handles.s' num2str(section) '_volslider,''Value'', val);']); case 'vol_slider' section = handles.section; eval(['set(handles.s' num2str(section) '_vol,''String'',num2str(get(handles.s' num2str(section) '_volslider,''Value''),2));']); case 'close' close_figure(f,figname(1:end-4)); return; end set(f,'UserData',handles); % -------------------------------------------------------------------- % This function taken from DSPFirst function y = mattostr(x,style) %MATTOSTR %------- % usage: mattostr(X,STYLE) % convert an entire matrix X to formatted numbers, % using a C format in STYLE, e.g., '%3.f' % version 4.x only....v4 handles NaN in printf [N,M] = size(x); tt = sprintf(style,x.'); Lt = length(tt); y = reshape( tt, Lt/N, N ).'; % Compute random number between matrix numbers function [num] = getrand(var) if (size(var,2) > 1) num = var(1) + rand*(var(2)-var(1)); else num = var; end % -------------------------------------------------------------------- function env = getampenv(section, handles) eval(['contents = get(handles.s' num2str(section) '_ampenv,''String'');']); eval(['value = contents{get(handles.s' num2str(section) '_ampenv,''Value'')};']); env = [0 1 1 1]; switch lower(value) case 'flat' env = [0 1 1 1]; case 'percussive' env = [0 0 0.02 1 1 0]; case 'sustained' env = [0 0 0.2 1 0.7 1 1 0]; case 'wedge' env = [0 0 1 1]; case 'invwedge' env = [0 1 1 0]; case 'triangle' env = [0 0 0.5 1 1 0]; case 'random' segments = floor(10*rand)+1; env = zeros(1,segments*2); time = cumsum([0 rand(1,segments-1)]); time = time./max(time); val = rand(1,segments); val = val./max(val); for i=1:segments, env(2*i-1) = time(i); env(2*i) = val(i); end case 'create' end % -------------------------------------------------------------------- function env = getfreqenv(section, handles) eval(['contents = get(handles.s' num2str(section) '_freqenv,''String'');']); eval(['value = contents{get(handles.s' num2str(section) '_freqenv,''Value'')};']); env = [0 1 1 1]; switch lower(value) case 'flat' env = [0 0 1 0]; case 'upsweep' env = [0 0 1 1]; case 'downsweep' env = [0 1 1 0]; case 'triangle' env = [0 0 0.5 1 1 0]; case 'random' segments = floor(10*rand)+1; env = zeros(1,segments*2); time = cumsum([0 rand(1,segments-1)]); time = time./max(time); val = rand(1,segments); val = val./max(val); for i=1:segments, env(2*i-1) = time(i); env(2*i) = val(i); end case 'create' end function specsound(handles) Fs = handles.Fs; section = handles.section; eval(['signal = handles.signal_' num2str(section) ';']); if (max(signal) > 1.0) signal = normalize(signal); end audiodata.data = signal'; audiodata.Fs = 44100; sonoexpogui(audiodata); % -------------------------------------------------------------------- % Fix this so that the proper button is relabeled 'Stop' % -------------------------------------------------------------------- function playsound(handles) Fs = handles.Fs; section = handles.section; eval(['signal = handles.signal_' num2str(section) ';']); if (section ~= 0) eval(['vol = str2double(get(handles.s' num2str(section) '_vol,''String''));']); else vol = 1.0; end eval(['hObject = handles.s' num2str(section) '_play;']); %eval(['buttonstring = get(handles.s' num2str(section) '_play,''String'');']); buttonstring = get(hObject,'String'); if (strncmp(buttonstring,'Play',4)) signal = signal.*vol; if (max(signal) > 1.0) signal = signal./(max(signal) + 0.2); end ud.hButton = hObject; if (isunix) signal(length(signal):length(signal)+Fs) = 0; end handles.p = handle(com.mathworks.toolbox.audio.JavaAudioPlayer(signal,Fs,16)); set(handles.p, 'UserData', ud); set(handles.p, 'StopFcn', @play_Ended); handles.p.play; if (section ~= 0) set(ud.hButton,'String','Stop'); else set(ud.hButton,'String','Stop All'); end else if (~isunix) handles.p.stop; end end function play_Ended(hObject, event) ud = get(hObject, 'UserData'); set(ud(1).hButton,'String','Play'); % -------------------------------------------------------------------- function getSpectrum(hObject, eventdata, handles) global Fs; path(path,'/home/bob/gibson'); section = handles.section; eval(['signal = handles.signal_' num2str(section) ';']); sonoexpo2(signal, Fs); % -------------------------------------------------------------------- function plotsound(handles) section = handles.section; Fs = handles.Fs; eval(['signal = handles.signal_' num2str(section) ';']); if (section ~= 0) eval(['vol = str2double(get(handles.s' num2str(section) '_vol,''String''));']); else vol = 1; end if (exist('signal')) signal = signal.*vol; sig_plot = figure; % We need to create a new figure and store the audio data in it! t = (0:length(signal)-1)./Fs; han = plot(t,signal); %set(han, 'XLim', [0 max(t)]); eval(['title(''Section' num2str(section) ''');']); xlabel('Time'); plotplay = uicontrol('String','Play',... 'Position',[5 40 40 20],... 'Callback','stochofn play'); posplay = get(plotplay,'Position'); plotspec = uicontrol('String','Spectrum',... 'Position',posplay + [0 -25 20 0],... 'Callback','stochofn spectrum'); handles.hObject = plotplay; set(han,'UserData',handles); else % Error popup; end function signal = mixsections(handles) Fs = handles.Fs; mix = []; samples = 0; if (get(handles.s1_mix,'Value')) volume = str2double(get(handles.s1_vol,'String')); signal_1 = handles.signal_1.*volume; start_1 = str2double(get(handles.s1_start,'String')); mix = [mix 1]; samples = max(samples,start_1*Fs+length(signal_1)+1); end if (get(handles.s2_mix,'Value')) volume = str2double(get(handles.s2_vol,'String')); signal_2 = handles.signal_2.*volume; start_2 = str2double(get(handles.s2_start,'String')); mix = [mix 2]; samples = max(samples,start_2*Fs+length(signal_2)+1); end if (get(handles.s3_mix,'Value')) volume = str2double(get(handles.s3_vol,'String')); signal_3 = handles.signal_3.*volume; start_3 = str2double(get(handles.s3_start,'String')); mix = [mix 3]; samples = max(samples,start_3*Fs+length(signal_3)+1); end if (samples == 0) return end signal = zeros(1,samples); for i=mix, eval(['starti = start_' num2str(i) '*Fs+1;']); eval(['lengthi = length(signal_' num2str(i) ');']); eval(['tempsig = signal_' num2str(i) ';']); signal(starti:lengthi+starti-1)=signal(starti:lengthi+starti-1)+tempsig; end % -------------------------------------------------------------------- function signal = synthesize(handles,section) Fs = 44100; channels = 1; numnotes = str2double(eval(['get(handles.s' num2str(section) '_numnotes,''String'')'])); percent_overlap = str2double(eval(['get(handles.s' num2str(section) '_overlap,''String'')'])); start_string = eval(['get(handles.s' num2str(section) '_start,''String'')']); if (strncmp(start_string,'0 (',3)) start_string = '0'; end start = eval(['[' start_string ']']); npartials_string = eval(['get(handles.s' num2str(section) '_npartials,''String'')']); if (strncmp(npartials_string,'min',3)) npartials_string = '1 3'; end num_partials = eval(['[' npartials_string ']']); partials_string = eval(['get(handles.s' num2str(section) '_partials,''String'')']); if (strncmp(partials_string,'mul',3)) partials_string = '1 1 2.05 0.5 3.2 0.2'; end partials = eval(['[' partials_string ']']); durs_string = eval(['get(handles.s' num2str(section) '_durs,''String'')']); if (strncmp(durs_string,'min',3)) durs_string = '0.1 1'; end durs = eval(['[' durs_string ']']); amps_string = eval(['get(handles.s' num2str(section) '_amps,''String'')']); if (strncmp(amps_string,'min',3)) amps_string = '0.0 1'; end amps = eval(['[' amps_string ']']); freqs_string = eval(['get(handles.s' num2str(section) '_freqs,''String'')']); if (strncmp(freqs_string,'min',3)) freqs_string = '100 1000'; end freqs = eval(['[' freqs_string ']']); fskews_string = eval(['get(handles.s' num2str(section) '_fskews,''String'')']); if (strncmp(fskews_string,'min',3)) fskews_string = '0.2 0.9'; end fskews = eval(['[' fskews_string ']']); matstring = mattostr(num_partials, '%d '); eval(['set(handles.s' num2str(section) '_npartials,''String'',''' matstring ''')']); matstring = mattostr(partials, '%2.2f '); eval(['set(handles.s' num2str(section) '_partials,''String'',''' matstring ''')']); matstring = mattostr(durs, '%2.2f '); eval(['set(handles.s' num2str(section) '_durs,''String'',''' matstring ''')']); matstring = mattostr(amps, '%2.2f '); eval(['set(handles.s' num2str(section) '_amps,''String'',''' matstring ''')']); matstring = mattostr(freqs, '%2.2f '); eval(['set(handles.s' num2str(section) '_freqs,''String'',''' matstring ''')']); matstring = mattostr(fskews, '%2.2f '); eval(['set(handles.s' num2str(section) '_fskews,''String'',''' matstring ''')']); eval(['set(handles.s' num2str(section) '_start,''String'',''' num2str(start) ''')']); % Get envelopes eval(['contents = get(handles.s' num2str(section) '_ampenv,''String'');']); eval(['avalue = contents{get(handles.s' num2str(section) '_ampenv,''Value'')};']); eval(['contents = get(handles.s' num2str(section) '_freqenv,''String'');']); eval(['fvalue = contents{get(handles.s' num2str(section) '_freqenv,''Value'')};']); ampenv = getampenv(section, handles); freqenv = getfreqenv(section, handles); pscore = cell(numnotes,8); begin = 0; dur = 0; for i=1:numnotes, begin = begin + dur*(1 - percent_overlap/100); amp = getrand(amps); num_p = floor(getrand(num_partials)); if (num_p > length(partials)/2); partamps = rand(1,num_p).*exp(-(1:num_p)/5); partfs = cumsum([1 rand(1,num_p-1)]); for j=1:num_p, parts(2*j-1) = partfs(j); parts(2*j) = partamps(j); end else parts = partials(1:2*num_p); end dur = getrand(durs); freq = getrand(freqs); fskew = getrand(fskews)*freq; if (strcmp(lower(avalue),'random')) ampenv = getampenv(section, handles); end if (strcmp(lower(fvalue),'random')) freqenv = getfreqenv(section, handles); end pscore(i,:) = {begin dur freq fskew amp freqenv ampenv parts}; end signal = synth(pscore, Fs,'add'); % -------------------------------------------------------------------- function handles = load_settings(handles) [file, path] = uigetfile({'*.mat','MATLAB datafile'}, 'Open'); load([path file]); % Set text entry items hs = {'start', 'numnotes', 'overlap', 'npartials'... 'partials', 'durs', 'amps', 'freqs', 'fskews', 'vol'}; for j=1:size(hs,2), for i=1:3, eval(['set(handles.s' num2str(i) '_' hs{j} ',''String'', s'... num2str(i) '_' hs{j} ')']); end end % Set remaining items hs = {'ampenv','freqenv','mix'}; for j=1:size(hs,2), for i=1:3, eval(['set(handles.s' num2str(i) '_' hs{j} ',''Value'', s'... num2str(i) '_' hs{j} ')']); end end set(handles.s1_volslider,'Value',str2double(get(handles.s1_vol,'String'))); set(handles.s2_volslider,'Value',str2double(get(handles.s2_vol,'String'))); set(handles.s3_volslider,'Value',str2double(get(handles.s3_vol,'String'))); handles.signal_1 = signal_1; handles.signal_2 = signal_2; handles.signal_3 = signal_3; function save_settings(handles) [file, path] = uiputfile({'*.mat','MATLAB datafile'}, 'Save as'); % Save these variables savestring = []; % Take care of single values hs = {'start', 'numnotes', 'overlap', 'npartials'... 'partials', 'durs', 'amps', 'freqs', 'fskews', 'vol'}; for j=1:size(hs,2), for i=1:3, eval(['s' num2str(i) '_' hs{j} '= get(handles.s'... num2str(i) '_' hs{j} ',''String'');']); savestring = [savestring '''s' num2str(i) '_' hs{j} ''',']; end end % Take care of popup menu items hs = {'ampenv','freqenv','mix'}; for j=1:size(hs,2), for i=1:3, eval(['s' num2str(i) '_' hs{j} '= get(handles.s'... num2str(i) '_' hs{j} ',''Value'');']); savestring = [savestring '''s' num2str(i) '_' hs{j} ''',']; end end % Remove last comma savestring = savestring(1:end-1); % Save sound data too? signal_1 = handles.signal_1; signal_2 = handles.signal_2; signal_3 = handles.signal_3; savestring = [savestring ', ''signal_1'', ''signal_2'', ''signal_3''']; % Check vaidity of savestring %['save([path file],' savestring ')'] eval(['save([path file],' savestring ');']); function write_soundfile(handles) Fs = handles.Fs; signal = mixsections(handles); if (max(abs(signal)) > 1) signal = signal./(max(signal)+0.1); end [file, path] = uiputfile({'*.wav','WAV'}, 'Save as'); wavwrite(signal,Fs,16,[path file]);