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

    function modexpofn(action)

	if nargin < 1
		action='init';
	end

	% Fix singlesideband
	% Time zoom resets
	% Create demodulation

	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;
            movegui(f,'center');
			reset(handles.sig_1_spec);
			reset(handles.sig_2_spec);
			reset(handles.sig_3_spec);
			reset(handles.sig_1_time);
			reset(handles.sig_2_time);
			reset(handles.sig_3_time);
			handles.fileopen = {false, false, false};
			set(handles.freqzoom,'Value',1);
		case 'loadsound'
			signum = handles.signum;
			handles.audio{signum} = load_audiodata;
            if ~isfield(handles.audio{signum}, 'filenamepath')
                return;
            end
            if (size(handles.audio{signum}.data,2) > 1)
                handles.audio{signum}.data = to_mono(handles.audio{signum}.data);
            end
            handles.fileopen{signum} = true;
			if signum == 2 & handles.fileopen{1}
				while length(handles.audio{1}.data) > length(handles.audio{2}.data)
					handles.audio{2}.data = [handles.audio{2}.data; handles.audio{2}.data];
				end
				handles.audio{2}.data = handles.audio{2}.data(1:length(handles.audio{1}.data));
			elseif signum == 1 & handles.fileopen{2}
				while length(handles.audio{1}.data) > length(handles.audio{2}.data)
					handles.audio{2}.data = [handles.audio{2}.data; handles.audio{2}.data];
				end
				handles.audio{2}.data = handles.audio{2}.data(1:length(handles.audio{1}.data));
			end
			contents = get(handles.fftsize,'String');
            fftsize = str2double(contents{get(handles.fftsize,'Value')});
            contents = get(handles.window,'String');
            shape = contents{get(handles.window,'Value')};
			[handles.audio{signum}.spectrum,...
             handles.audio{signum}.bin,...
             handles.audio{signum}.st] = ...
                spectrogram(handles.audio{signum}, fftsize, shape);
			set(f,'UserData',handles);
			loadSpecPlot(handles, signum);
			loadTimePlot(handles, signum);
			linkedzoom([handles.sig_1_time, handles.sig_1_spec,...
				handles.sig_2_time, handles.sig_2_spec, ...
				handles.sig_3_time, handles.sig_3_spec],'onx');
			modexpofn 'freqzoom';
			timeplot = eval(['handles.sig_' num2str(signum) '_time']);
			handles.xlim_orig = get(timeplot,'XLim');
			modexpofn 'freqzoom';
		case 'write_soundfile'
			if (handles.fileopen{2})
				write_soundfile(handles);
			end
        case 'write_modsoundfile'
			if (handles.fileopen{3})
				write_soundfile(handles);
			end
		case 'play'
			signum = handles.signum;
            if (handles.fileopen{signum})
				timeplot = eval(['handles.sig_' num2str(signum) '_time']);
				samples = round(get(timeplot,'XLim').*handles.audio{signum}.Fs+1);
				if samples(1) <= 0
					samples(1) = 1;
				elseif samples(2) > length(handles.audio{signum}.data)
					samples(2) = length(handles.audio{signum}.data);
				end
                audiodata.data = handles.audio{signum}.data(samples(1):samples(2));
                audiodata.Fs = handles.audio{signum}.Fs;
                eval(['playbutton = handles.s' num2str(signum) '_play;']);
                play_audiodata(audiodata, playbutton);
            end
		case {'fftsize','window'}
			for signum = 1:3
				if (handles.fileopen{signum})
					contents = get(handles.fftsize,'String');
					fftsize = str2double(contents{get(handles.fftsize,'Value')});
					contents = get(handles.window,'String');
					shape = contents{get(handles.window,'Value')};
					[handles.audio{signum}.spectrum,...
					 handles.audio{signum}.bin,...
					 handles.audio{signum}.st] = ...
						spectrogram(handles.audio{signum}, fftsize, shape);
					loadSpecPlot(handles, signum);
				end
			end
			modexpofn 'freqzoom';
		case {'db','colormap','inverse','interpolate'}
			for signum = 1:3
				if (handles.fileopen{signum})
					eval(['timeplot = handles.sig_' num2str(signum) '_time;']);
					xlim = get(timeplot,'XLim');
					eval(['spectrumplot = handles.sig_' num2str(signum) '_spec;']);
					loadSpecPlot(handles, signum);
					set(spectrumplot,'XLim',xlim);
				end
			end
			modexpofn 'freqzoom';
		case 'create_modsig'
			% Open new GUI window to create modulation signal
			[freqenv,ampenv] = modsig;
			if handles.fileopen{2}
				Fs = handles.audio{2}.Fs;
				samples = length(handles.audio{2}.data);
			else
				Fs = 44100;
				samples = 1*Fs;
			end
			signum = 1;
			handles.audio{signum} = calculate_sig(freqenv,ampenv,samples,Fs);
			handles.fileopen{signum} = true;
			contents = get(handles.fftsize,'String');
			fftsize = str2double(contents{get(handles.fftsize,'Value')});
			contents = get(handles.window,'String');
			shape = contents{get(handles.window,'Value')};
			[handles.audio{signum}.spectrum,...
			 handles.audio{signum}.bin,...
			 handles.audio{signum}.st] = ...
				spectrogram(handles.audio{signum}, fftsize, shape);
			loadSpecPlot(handles, signum);
			loadTimePlot(handles, signum);
			set(f,'UserData',handles);
			modexpofn 'freqzoom';
		case 'create_carsig'
			% Open new GUI window to create modulation signal
			[freqenv,ampenv] = modsig;
			if handles.fileopen{1}
				Fs = handles.audio{1}.Fs;
				samples = length(handles.audio{1}.data);
			else
				Fs = 44100;
				samples = 1*Fs;
			end
			signum = 2;
			handles.audio{signum} = calculate_sig(freqenv,ampenv,samples,Fs);
			handles.fileopen{signum} = true;
			contents = get(handles.fftsize,'String');
			fftsize = str2double(contents{get(handles.fftsize,'Value')});
			contents = get(handles.window,'String');
			shape = contents{get(handles.window,'Value')};
			[handles.audio{signum}.spectrum,...
			 handles.audio{signum}.bin,...
			 handles.audio{signum}.st] = ...
				spectrogram(handles.audio{signum}, fftsize, shape);
			loadSpecPlot(handles, signum);
			loadTimePlot(handles, signum);
			set(f,'UserData',handles);
			modexpofn 'freqzoom';
		case 'amdsbsc'
			if (handles.fileopen{1} & handles.fileopen{2})
				handles = amdsbsc(handles);
				set(f,'UserData',handles);
				signum = 3;
				contents = get(handles.fftsize,'String');
				fftsize = str2double(contents{get(handles.fftsize,'Value')});
				contents = get(handles.window,'String');
				shape = contents{get(handles.window,'Value')};
				[handles.audio{signum}.spectrum,...
				 handles.audio{signum}.bin,...
				 handles.audio{signum}.st] = ...
					spectrogram(handles.audio{signum}, fftsize, shape);
				loadSpecPlot(handles, signum);
				loadTimePlot(handles, signum);
				modexpofn 'freqzoom';
			else
				warndlg(['You must open two files to perform modulation ', ...
					' synthesis!'],'Error');
			end
		case 'amdsbtc'
			if (handles.fileopen{1} & handles.fileopen{2})
				handles = amdsbtc(handles);
				set(f,'UserData',handles);
				signum = 3;
				contents = get(handles.fftsize,'String');
				fftsize = str2double(contents{get(handles.fftsize,'Value')});
				contents = get(handles.window,'String');
				shape = contents{get(handles.window,'Value')};
				[handles.audio{signum}.spectrum,...
				 handles.audio{signum}.bin,...
				 handles.audio{signum}.st] = ...
					spectrogram(handles.audio{signum}, fftsize, shape);
				loadSpecPlot(handles, signum);
				loadTimePlot(handles, signum);
				modexpofn 'freqzoom';
			else
				warndlg(['You must open two files to perform modulation ', ...
					' synthesis!'],'Error');
			end
        case 'ssbsc'
			if (handles.fileopen{1} & handles.fileopen{2})
				handles = ssbsc(handles);
				set(f,'UserData',handles);
				signum = 3;
				contents = get(handles.fftsize,'String');
				fftsize = str2double(contents{get(handles.fftsize,'Value')});
				contents = get(handles.window,'String');
				shape = contents{get(handles.window,'Value')};
				[handles.audio{signum}.spectrum,...
				 handles.audio{signum}.bin,...
				 handles.audio{signum}.st] = ...
					spectrogram(handles.audio{signum}, fftsize, shape);
				loadSpecPlot(handles, signum);
				loadTimePlot(handles, signum);
				modexpofn 'freqzoom';
			else
				warndlg(['You must open two files to perform modulation ', ...
					' synthesis!'],'Error');
			end
		case 'loadworkspace'
			handles = loadworkspace(handles);
			set(f,'UserData',handles);
			for signum=1:3,
				if (handles.fileopen{signum})
					loadSpecPlot(handles, signum);
					loadTimePlot(handles, signum);
				end
			end
		case 'saveworkspace'
			saveworkspace(handles);
        case 'zoomreset'
			if isfield(handles,'xlim_orig')
				for signum=1:3
					timeplot = eval(['handles.sig_' num2str(signum) '_time']);
					specplot = eval(['handles.sig_' num2str(signum) '_spec']);
					set(timeplot,'XLim',handles.xlim_orig);
					set(specplot,'XLim',handles.xlim_orig);
				end
            end
			linkedzoom([handles.sig_1_time, handles.sig_1_spec,...
				handles.sig_2_time, handles.sig_2_spec, ...
				handles.sig_3_time, handles.sig_3_spec],'onx');
		case 'freqzoom'
            val = get(handles.freqzoom,'Value');
            if val == 0,
                val = 0.001;
            end
            for signum = 1:3
                specplot = eval(['handles.sig_' num2str(signum) '_spec']);
                if (handles.fileopen{signum})
                    Fs = handles.audio{signum}.Fs;
                    set(specplot,'YLim',[0 val*Fs/2])
                end
            end
        case 'fourier'
			if handles.fileopen{3}
				fourierexpogui(handles.audio{3});
			end
        case 'print'
            print_figure(f);
        case 'close'
            close_figure(f,figname(1:end-4));
            return;
	end
	set(f,'UserData',handles);


% --------------------------------------------------------------------
function loadTimePlot(handles, signum)
	Fs = handles.audio{signum}.Fs;
	t = [0:1/Fs:(length(handles.audio{signum}.data)-1)/Fs];
	eval(['timeplot = handles.sig_' num2str(signum) '_time;']);
	axes(timeplot)
    plot(t,handles.audio{signum}.data)
    maxtime = length(t)/Fs;
    set(timeplot,'XLim',[0 maxtime]);
    set(timeplot,'YLim',[-1.1 1.1]);
	if (signum ~= 1)
		set(timeplot,'YTickLabel',['']);
	end
    grid;
    xlabel('time (s)');
    
% --------------------------------------------------------------------
function loadSpecPlot(handles, signum)
	Fs = handles.audio{signum}.Fs;
	eval(['spectrumplot = handles.sig_' num2str(signum) '_spec;']);
    axes(spectrumplot);
    handles.pos = get(gca,'Position'); % Save axes position
    if (get(handles.interpolate,'Value'))
        if (get(handles.dB,'Value'))
            pcolor(handles.audio{signum}.st,handles.audio{signum}.bin,...
				20*log10(abs(handles.audio{signum}.spectrum)));
        else
            pcolor(handles.audio{signum}.st,handles.audio{signum}.bin,...
				abs(handles.audio{signum}.spectrum));
        end
        shading interp;
    else
        if (get(handles.dB,'Value'))
            imagesc(handles.audio{signum}.st,handles.audio{signum}.bin,...
				20*log10(abs(handles.audio{signum}.spectrum)));
        else
            imagesc(handles.audio{signum}.st,handles.audio{signum}.bin,...
				abs(handles.audio{signum}.spectrum));
        end
    end

    axis xy;
	ylabel('Frequency (Hz)');
	if (signum ~= 1)
		ylabel('');
		set(spectrumplot,'YTickLabel',['']);
	end
	contents = get(handles.colormap,'String');
    cmap = colormap(lower(contents{get(handles.colormap,'Value')}));
	if (get(handles.inverse,'Value'))
		cmap = flipud(cmap);
	end
	colormap(cmap);
    set(spectrumplot,'XTickLabel',['']);

    ha = axes('position',[0.15+(signum-1)*0.31 0.15 0.075 0.015]);
    set(ha,'Visible','off');

	ts = 5.5;
    to = 2;

	info = sprintf(['Filename: %s\n Duration: %s seconds\n Fs: %s Hz'], ...
        handles.audio{signum}.filenamepath, ...
        num2str(length(handles.audio{signum}.data)/Fs), ...
        num2str(Fs));

    eval(['set(handles.text' num2str(signum) ',''String'', info);']);


% --------------------------------------------------------------------
function handles = loadworkspace(handles)
	[file, path] = uigetfile({'*.mat','MATLAB datafile'}, 'Open');
	load([path file]);
	set(handles.colormap,'Value',graphprops{1});
	set(handles.window,'Value',graphprops{2});
	set(handles.fftsize,'Value',graphprops{3});
	set(handles.inverse,'Value',graphprops{4});
	set(handles.dB,'Value',graphprops{5});
	set(handles.interpolate,'Value',graphprops{6});
	for signum=1:3,
		if (openfiles{signum})
			handles.fileopen{signum} = true;
			handles.audio{signum} = audio{signum};
		end
	end

% --------------------------------------------------------------------
function handles = amdsbsc(handles)
	signal_1 = handles.audio{1}.data; % Carrier
	signal_2 = handles.audio{2}.data; % Modulator
	samples = length(signal_1);
	while length(signal_1) > length(signal_2)
		signal_2 = [signal_2; signal_2];
	end
	Fs = handles.audio{1}.Fs;
	filename = ['AM-DSBSC'];
	audiodata = normalize(signal_1(1:samples).*signal_2(1:samples));
	handles.audio{3}.t = [0:1/Fs:(length(audiodata)-1)/Fs];
	handles.audio{3}.filenamepath = filename;
	handles.audio{3}.Fs = Fs;
	handles.audio{3}.data = audiodata;
	signum = 3;
	contents = get(handles.fftsize,'String');
	fftsize = str2double(contents{get(handles.fftsize,'Value')});
	contents = get(handles.window,'String');
	shape = contents{get(handles.window,'Value')};
	[handles.audio{signum}.spectrum,...
	 handles.audio{signum}.bin,...
	 handles.audio{signum}.st] = ...
		spectrogram(handles.audio{signum}, fftsize, shape);
	handles.fileopen{3} = true;


function handles = amdsbtc(handles)
	% In the future scale sound to be envelope to be exactly the length
	% of the sound it is being applied to.
	signal_1 = handles.audio{1}.data;
	signal_2 = handles.audio{2}.data;
	% Make unipolar
	%signal_1 = signal_1 + min(signal_1);
    signal_1 = signal_1 + 2;
	samples = length(signal_1);
	while length(signal_1) > length(signal_2)
		signal_2 = [signal_2; signal_2];
	end
	Fs = handles.audio{1}.Fs;
	filename = ['AM-DSBTC'];
	am_offset = 1.5;
	audiodata = normalize((signal_1(1:samples)+am_offset).*signal_2(1:samples));
	handles.audio{3}.t = [0:1/Fs:(length(audiodata)-1)/Fs];
	handles.audio{3}.filenamepath = filename;
	handles.audio{3}.Fs = Fs;
	handles.audio{3}.data = audiodata;
	signum = 3;
	contents = get(handles.fftsize,'String');
	fftsize = str2double(contents{get(handles.fftsize,'Value')});
	contents = get(handles.window,'String');
	shape = contents{get(handles.window,'Value')};
	[handles.audio{signum}.spectrum,...
	 handles.audio{signum}.bin,...
	 handles.audio{signum}.st] = ...
		spectrogram(handles.audio{signum}, fftsize, shape);
	handles.fileopen{3} = true;

% Sing sideband transmitted carrier
function handles = ssbsc(handles)
	signal_1 = handles.audio{1}.audiodata;
	signal_2 = handles.audio{2}.audiodata;
	if (length(signal_2) > length(signal_1))
		samples = length(signal_1);
	else
		samples = length(signal_2);
	end	
	Fs = handles.audio{1}.Fs;
	filename = ['SSBSC'];
	audiodata = signal_1(1:samples).*signal_2(1:samples);
    % Uknown if this is correct...
    audiodataH = hilbert(signal_1(1:samples)).*hilbert(signal_2(1:samples));
    % Hilbert transform
    %audiodataH = hilbert(audiodata);
    % Retain uppersideband (lower sideband = '+')
    audiodata = audiodata - audiodataH;
	audiodata = real(audiodata);
    
	handles.audio{3}.t = [0:1/Fs:(length(audiodata)-1)/Fs];
	handles.audio{3}.filenamepath = filename;
	handles.audio{3}.Fs = Fs;
	% Normalize
	if (max(abs(audiodata)) > 1.0)
		audiodata = audiodata./max(abs(audiodata)+0.1);
	end
	handles.audio{3}.audiodata = audiodata;
	signum = 3;
	contents = get(handles.fftsize,'String');
	fftsize = str2double(contents{get(handles.fftsize,'Value')});
	contents = get(handles.window,'String');
	shape = contents{get(handles.window,'Value')};
	[handles.audio{signum}.spectrum,...
	 handles.audio{signum}.bin,...
	 handles.audio{signum}.st] = ...
		spectrogram(handles.audio{signum}, fftsize, shape);
	handles.fileopen{3} = true;
    
% --------------------------------------------------------------------
function saveworkspace(handles)
	[file, path] = uiputfile({'*.mat','MATLAB datafile'}, 'Save as');
    % Save these variables
	audio = handles.audio;
	openfiles = handles.fileopen;
	graphprops = {get(handles.colormap,'Value'), ...
				get(handles.window,'Value'),...
				get(handles.fftsize,'Value'),...
				get(handles.inverse,'Value'),...
				get(handles.dB,'Value'),...
				get(handles.interpolate,'Value')};
    save([path file], 'audio','openfiles','graphprops');


function audiodata = calculate_sig(freqenv,ampenv,varargin)
	switch nargin
		case 2
			Fs = 44100;
			samples = Fs;
		case 3
			samples = varargin{1};
			Fs = 44100;
		case 4
			samples = varargin{1};
			Fs = varargin{2};
	end
	minfreq = min(freqenv(2:2:end));
	maxfreq = max(freqenv(2:2:end));
	if (minfreq ~= maxfreq)
		freqenv(2:2:end) = freqenv(2:2:end) - minfreq;
		freqskew = max(freqenv(2:2:end));
		freqenv(2:2:end) = freqenv(2:2:end)./freqskew;
	else
		freqskew = 0;
		freqenv(2:2:end) = freqenv(2:2:end)./minfreq;
	end

	amp = 1;
	% Synthesize modulation signal
	audiodata = additive(samples, minfreq, freqskew, amp, ...
			 {freqenv}, {ampenv}, {[1 1]}, Fs);
	audiodata.data = audiodata';
	audiodata.filenamepath = ' ';
	audiodata.Fs = Fs;
	audiodata.nbits = 16;


%function save_modulation_soundfile_Callback(hObject, eventdata, handles)
%	signum = 2;
%	if (handles.fileopen{signum})
%		% Popup menu to write soundfile to
%		[filename, pathname] = uiputfile('*.wav', 'Save sound as');
%		if isequal(filename,0) | isequal(pathname,0)
%			return;
%		end
%		signal = handles.audio{signum}.audiodata;
%		Fs = handles.audio{signum}.Fs;
%		if (max(abs(signal)) > 0.9) 
%			signal = signal./max(abs(signal)+0.1);
%		end
%		wavwrite(signal,Fs,16,[pathname filename]);
%		disp(['File saved as ', fullfile(pathname, filename)])
%	end