home *** CD-ROM | disk | FTP | other *** search
- function sigdemo1(action,in1,in2);
- %SIGDEMO1 Interactive signal demo - 1 : DFT of a signal
- % Demonstrates MATLAB's graphic user interface using Handle Graphics
- % while illustrating some basic signal processing concepts, such as
- % sampling, aliasing, and windowing.
-
- % Author: T. Krauss
- % 11/3/92, updated 2/9/93
- % (c) Copyright 1984-93, by The MathWorks, Inc.
-
- % possible actions:
- % 'start'
- % 'down'
- % 'move'
- % 'up'
- % 'redraw'
- % 'done'
- % 'setwindow'
- % 'showwind'
-
- if nargin<1,
- action='start';
- end;
-
- global SIGDEMO1_DAT
-
- if strcmp(action,'start'),
- % graphics initialization
- clf reset;
- set(gcf,'Units','normalized','backingstore','off');
-
- popup=uicontrol('Style','Popup','String','cosine|square|sawtooth',...
- 'Position',[.03 .02 .2 .08],'Units','normalized',...
- 'CallBack','sigdemo1(''redraw'')');
-
- if exist('freqz')==2,
- wind_menu=uimenu('Label','Window');
- w1=uimenu(wind_menu,'Label','rectangular','Callback',...
- 'sigdemo1(''setwindow'',1)');
- w2=uimenu(wind_menu,'Label','triangular','Callback',...
- 'sigdemo1(''setwindow'',2)');
- w3=uimenu(wind_menu,'Label','hanning','Callback',...
- 'sigdemo1(''setwindow'',3)');
- w4=uimenu(wind_menu,'Label','hamming','Callback',...
- 'sigdemo1(''setwindow'',4)');
- w5=uimenu(wind_menu,'Label','chebyshev');
- w5_20=uimenu(w5,'Label','20 dB atten.','Callback',...
- 'sigdemo1(''setwindow'',5,20)');
- w5_30=uimenu(w5,'Label','30 dB atten.','Callback',...
- 'sigdemo1(''setwindow'',5,30)');
- w5_40=uimenu(w5,'Label','40 dB atten.','Callback',...
- 'sigdemo1(''setwindow'',5,40)');
- w6=uimenu(wind_menu,'Label','kaiser');
- w6_1=uimenu(w6,'Label','parameter = 1','callback',...
- 'sigdemo1(''setwindow'',6,1)');
- w6_15=uimenu(w6,'Label','parameter = 4','callback',...
- 'sigdemo1(''setwindow'',6,4)');
- w6_2=uimenu(w6,'Label','parameter = 9','callback',...
- 'sigdemo1(''setwindow'',6,9)');
- w7=uimenu(wind_menu,'Label','Show window...',...
- 'Callback','sigdemo1(''showwind'');');
- end; % if statement
-
- freq_text=uicontrol('Style','text','Position',[.33 .02 .28 .08],...
- 'Units','normalized','BackgroundColor','black',...
- 'ForegroundColor','white','String','Fundamental (Hertz):',...
- 'HorizontalAlignment','right');
-
- freq_field=uicontrol('Style','edit','Position',[.63 .02 .12 .08],...
- 'Units','normalized','String','5',...
- 'CallBack','sigdemo1(''setfreq''); sigdemo1(''redraw'')');
-
- done_button=uicontrol('Style','Pushbutton','Position',[.85 .02 ...
- .12 .08],'Units','normalized','Callback',...
- 'sigdemo1(''done'')','String','Done');
-
- help sig1help % show help in command window
-
- % Create intial signal
- N=201; % number of samples
- % N=21;
- amp=0.5;
- freq=5; % hertz
- t0=0; % seconds
- t1=1; % seconds
- t=linspace(t0,t1,N)';
- T=(t1-t0)/N; % sampling rate in seconds
- M=256; % length of fft
- window=ones(N,1); % use window to lower side-lobes in the freq. domain
- % (makes peaks wider)
-
- min_dB = -40; % freq. domain lower axis limit
-
- % create axes for time domain and frequency domain plot
- ax_freq=axes('Position',[.15 .2 .8 .3],'XLim',...
- [0 1/(2*T)],'YLim',[min_dB 50]);
-
- % time domain
- val = get(popup,'Value');
- if (val == 1),
- f=amp*cos(freq*t*2*pi);
- elseif (val == 2), % square wave
- tt=freq*t*2*pi;
- tmp=rem(tt,2*pi);
- f=amp*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
- elseif (val == 3), % sawtooth
- tt=freq*t*2*pi;
- f=amp*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
- end;
-
- % frequency domain
- F=fft(window.*f,2*M);
- F=F(1:M);
- w=(0:M-1)*pi/M;
- FF=20*log10(abs(F));
- ind=find(FF<min_dB);
- FF(ind)=NaN*ones(size(ind)); % put NaN's in where
- % min_dB shows up - this is to work around no clipping in xor mode
- freq_line=plot(w/2/pi/T,FF,'EraseMode','xor');
- axis([0 1/(2*T) min_dB 50]);
- grid;
- ylabel('Magnitude (dB)');
- xlabel('Frequency (Hertz)');
-
- ax_time=axes('Position',[.15 .62 .8 .3],'XLim',[t0 t1],'YLim',[-1 1]);
- time_line=plot(t,f,'EraseMode','xor');
- axis([t0 t1 -1 1]);
- % (set to xor mode to prevent re-rendering, that is, for speed)
- grid;
- ylabel('Waveform');
- xlabel('Time (Seconds)');
- title('Click and drag waveform to change fundamental and amplitude');
-
- set(time_line,'ButtonDownFcn','sigdemo1(''down'')');
- SIGDEMO1_DAT = [freq; amp; N; M; min_dB; 0; 0; ...
- time_line; freq_line; freq_field; popup; -1; gcf; t(:); window(:)];
-
- elseif strcmp(action,'down'),
- % assumes that a line was clicked
- time_line=SIGDEMO1_DAT(8);
- axes(get(time_line,'parent')); % set the right axes
-
- % Obtain coordinates of mouse click location in axes units
- pt=get(gca,'currentpoint');
- x=pt(1,1);
- y=pt(1,2);
-
-
- % find closest vertex of line to mouse click location (call it fixed_x, fixed_y)
-
- line_x=get(time_line,'XData');
- line_y=get(time_line,'YData');
- set(gca,'units','pixels'); % distance must bein pixels
- p=get(gca,'pos');
- xa=get(gca,'xlim');
- ya=get(gca,'ylim');
-
- dist=((line_x-x)*p(3)/(xa(2)-xa(1))).^2 + ...
- ((line_y-y)*p(4)/(ya(2)-ya(1))).^2;
- [temp,i]=min(dist);
- fixed_x=line_x(i);
- fixed_y=line_y(i);
- set(time_line,'LineStyle','--');
-
- SIGDEMO1_DAT(6)=fixed_x;
- SIGDEMO1_DAT(7)=fixed_y;
-
- set(gcf,'WindowButtonMotionFcn', 'sigdemo1(''move'')');
- set(gcf,'WindowButtonUpFcn', 'sigdemo1(''up'')');
- % set(gcf,'userdata',u);
-
- elseif strcmp(action,'move'),
- % u = get(gcf,'userdata');
- freq=SIGDEMO1_DAT(1);
- amp=SIGDEMO1_DAT(2);
- N=SIGDEMO1_DAT(3);
- M=SIGDEMO1_DAT(4);
- min_dB=SIGDEMO1_DAT(5);
- fixed_x=SIGDEMO1_DAT(6);
- fixed_y=SIGDEMO1_DAT(7);
- time_line=SIGDEMO1_DAT(8);
- freq_line=SIGDEMO1_DAT(9);
- freq_field=SIGDEMO1_DAT(10);
- popup=SIGDEMO1_DAT(11);
- t=SIGDEMO1_DAT(14:14+N-1);
- window=SIGDEMO1_DAT(14+N:14+N+N-1);
-
- pt=get(gca,'currentpoint');
- x=pt(1,1);
- y=pt(1,2);
-
- amp1=y/fixed_y*amp;
- if (abs(amp1)>1.0),
- amp1=1.0*sign(amp1);
- end;
- if (abs(amp1)<0.05),
- amp1=0.05*sign(amp1);
- end;
- freq1=fixed_x/x*freq;
-
- val = get(popup,'Value');
- if (val == 1),
- f=amp1*cos(freq1*t*2*pi);
- elseif (val == 2), % square wave
- tt=freq1*t*2*pi;
- tmp=rem(tt,2*pi);
- f=amp1*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
- elseif (val == 3), % sawtooth
- tt=freq1*t*2*pi;
- f=amp1*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
- end;
- set(time_line,'YData',f);
- F=fft(window.*f,2*M);
- F=F(1:M);
- w=(0:M-1)*pi/M;
- FF=20*log10(abs(F));
- ind=find(FF<min_dB);
- FF(ind)=NaN*ones(size(ind)); % put NaN's in where
- % min_dB shows up - this is to work around no clipping in xor mode
- set(freq_line,'YData',FF);
- set(freq_field,'String',num2str(freq1));
-
- elseif strcmp(action,'up'),
- pt=get(gca,'currentpoint');
- x=pt(1,1);
- y=pt(1,2);
-
- set(gcf,'WindowButtonMotionFcn','');
- set(gcf,'WindowButtonUpFcn','');
-
- % u=get(gcf,'userdata');
- freq=SIGDEMO1_DAT(1);
- amp=SIGDEMO1_DAT(2);
- fixed_x=SIGDEMO1_DAT(6);
- fixed_y=SIGDEMO1_DAT(7);
-
- amp1=y/fixed_y*amp;
- if (abs(amp1)>1.0),
- amp1=1.0*sign(amp1);
- end;
- if (abs(amp1)<0.05),
- amp1=0.05*sign(amp1);
- end;
- freq1=fixed_x/x*freq;
-
- set(SIGDEMO1_DAT(8),'linestyle','-');
- SIGDEMO1_DAT(1)=freq1; % set amplitude and frequency
- SIGDEMO1_DAT(2)=amp1;
- % set(gcf,'userdata',u);
- sigdemo1('redraw');
-
- elseif strcmp(action,'done'),
- % close the figure window that is showing the window fnction:
- % u = get(gcf,'userdata');
- if (SIGDEMO1_DAT(12)~=-1),
- close(SIGDEMO1_DAT(12));
- end;
- clf reset;
- clear global SIGDEMO1_DAT
-
- elseif strcmp(action,'redraw'),
- % recomputes time and frequency waveforms and updates display
- % u = get(gcf,'userdata');
- freq=SIGDEMO1_DAT(1);
- amp=SIGDEMO1_DAT(2);
- N=SIGDEMO1_DAT(3);
- M=SIGDEMO1_DAT(4);
- min_dB=SIGDEMO1_DAT(5);
- time_line=SIGDEMO1_DAT(8);
- freq_line=SIGDEMO1_DAT(9);
- freq_field=SIGDEMO1_DAT(10);
- popup=SIGDEMO1_DAT(11);
- t=SIGDEMO1_DAT(14:14+N-1);
- window=SIGDEMO1_DAT(14+N:14+N+N-1);
- val = get(popup,'Value');
- if (val == 1),
- f=amp*cos(freq*t*2*pi);
- elseif (val == 2), % square wave
- tt=freq*t*2*pi;
- tmp=rem(tt,2*pi);
- f=amp*(2*rem((tt<0)+(tmp>pi | tmp<-pi)+1,2)-1);
- elseif (val == 3), % sawtooth
- tt=freq*t*2*pi;
- f=amp*((tt < 0) + rem(tt,2*pi)/2/pi - .5)*2;
- end;
- set(time_line,'YData',f);
- F=fft(window.*f,2*M);
- F=F(1:M);
- w=(0:M-1)*pi/M;
- FF=20*log10(abs(F));
- ind=find(FF<min_dB);
- FF(ind)=NaN*ones(size(ind)); % put NaN's in where
- % min_dB shows up - this is to work around no clipping in xor mode
- set(freq_line,'YData',FF);
- set(freq_field,'String',num2str(freq));
-
- drawnow;
-
- elseif strcmp(action,'setwindow'),
- % u = get(gcf,'userdata');
- N=SIGDEMO1_DAT(3);
- if (in1==1),
- window = boxcar(N);
- elseif (in1==2),
- window = triang(N);
- elseif (in1==3),
- window = hanning(N);
- elseif (in1==4),
- window = hamming(N);
- elseif (in1==5),
- window = chebwin(N,in2);
- elseif (in1==6),
- window = kaiser(N,in2);
- end;
- SIGDEMO1_DAT(14+N:14+N+N-1)=window;
- % set(gcf,'userdata',u);
- sigdemo1('redraw');
- if (SIGDEMO1_DAT(12)~=-1),
- sigdemo1('showwind');
- end;
-
- elseif strcmp(action,'showwind'),
- % u=get(gcf,'userdata');
- oldfig=gcf;
- N=SIGDEMO1_DAT(3);
- t=SIGDEMO1_DAT(14:14+N-1);
- window=SIGDEMO1_DAT(14+N:14+N+N-1);
- if (SIGDEMO1_DAT(12)==-1),
- SIGDEMO1_DAT(12)=figure;
-
- axes('Position',[.15 .62 .8 .3]);
- line1=plot(t,window);
- title('Window function');
- xlabel('time (seconds)');
- grid;
- ylabel('Window');
-
- axes('Position',[.15 .2 .8 .3]);
- W=fft(window,1024);
- line2=plot((0:(1/1024):(.5-(1/1024)))*N,20*log10(abs(W(1:512))));
- set(gca,'xlim',[0 N/2]);
- xlabel('Frequency (Hz)');
- ylabel('Magnitude (dB)');
- grid;
- windclose=uicontrol('Style','Pushbutton','Position',[.85 .02 ...
- .12 .08],...
- 'Units','normalized','Callback',['THEHAND=get(gcf,''userdata'');'...
- 'close; figure(THEHAND(1)); global SIGDEMO1_DAT, '...
- 'SIGDEMO1_DAT(12)=-1; clear THEHAND SIGDEMO1_DAT'],'String','Close');
- set(gcf,'userdata',[oldfig line1 line2]);
- % set(oldfig,'userdata',u);
-
- else
- figure(SIGDEMO1_DAT(12));
- lines=get(gcf,'userdata');
- set(lines(2),'ydata',window);
- W=fft(window,1024);
- set(lines(3),'ydata',20*log10(abs(W(1:512))));
- drawnow
- end
-
- elseif strcmp(action,'setfreq'),
- % u = get(gcf,'userdata');
- SIGDEMO1_DAT(1)=str2num(get(SIGDEMO1_DAT(10),'string'));
- % set(gcf,'userdata',u);
-
- end
-
-