Home > matlab code, Uncategorized, youtube demo code > Negative Frequency GUI Code

Negative Frequency GUI Code

function negfgui(varargin)
% An interactive GUI which attempts to help students visualise negative frequencies
% by David Dorran, TU Dublin, March 2022
% reuses some code to track mouse movement from the zpgui function by Tom Krauss from Perdue University
% Youtube video explanation provided at https://youtu.be/Rxc_ypVdruw

global zero_locations diff_equ_text op_text_samps op_freq_pts op_points draw_plt disp_plt op_disp_plt freq_plt xyz_pts op_xyz_pts xy_pts ptr negfqui_fh freq_pts points text_samps b a y gain pole_vals zero_vals freq_resp_pts

buf_len = 50;
tail_len = 10;
max_points = 100000;
fft_len = 1024;
win_func = hamming(buf_len);

if nargin == 0
    action = 'init';
else
        action = varargin{1};
end

if(strcmp(class(action), 'matlab.ui.control.UIControl'))
    zero_vals = str2num(zero_locations.String);
    negfgui('update_freq_response');
end
switch action
    case 'init'
        zero_vals = [ -j j];
        pole_vals = [0 0];
        
        if(strcmp(class(negfqui_fh),'matlab.ui.Figure'))
            if(~isvalid(negfqui_fh))
                negfqui_fh = figure;    
            end
            if(nargin ==0)
                close(negfqui_fh);
                negfqui_fh = figure;  
            end
        else
            negfqui_fh = figure;
        end
        set(negfqui_fh,'position',[ 1          41        1366         651]);
        ptr = 1;
        points = ones(1,max_points)*NaN;
        op_points = ones(1,max_points)*NaN;
        
        freq_plt = subplot(2,3,1);
        fax = (([0:fft_len-1])/fft_len*2*pi)-pi;
        yyaxis left
        freq_pts = plot(fax,points(1:fft_len));
        hold on
        op_freq_pts = plot(fax,points(1:fft_len),'r');
        xlim([-pi pi])
        ylim([0 buf_len/2])
        ylabel('Magnitude Content')
        yyaxis right
        freq_resp_pts = plot(fax,points(1:fft_len));
        xlim([-pi pi])
        ylim([0 1])
        title('Double sided-spectrum');
        xlabel('frequency (radians per sample)')
        ylabel('Magnitude Response')
        draw_plt = subplot(2,3,2);
        xy_pts = plot([]);
        for m =1:tail_len
            hold on
            xy_pts(m) = plot(points(m)+points(m)*j,'r.','MarkerSize',tail_len-m+1);
        end
        ylabel('Y')
        xlabel('X')
        xlim([-1 1]);
        ylim([-1 1]);
        disp_plt = subplot(2,3,3);
        xyz_pts = plot3(real(points),imag(points),[0:length(points)-1]);
        hold on
        surf([0 0 ],[-1.1 1.1],[-1 length(points); -1 length(points)],'FaceAlpha',0.2)
        surf([-1.1 1.1], [ 0 0 ],[ length(points) length(points); -1 -1],'FaceAlpha',0.2)
        xlabel('X')
        ylabel('Y')
        zlabel('Samples')
        
        xlim([-1 1]);
        ylim([-1 1]);
        zlim([0 buf_len])
        set(gca,'CameraUpVector', [0 1 0 ])
        grid on
        set(draw_plt,'buttondownfcn', 'negfgui(''draw'')')
        
        op_disp_plt = subplot(2,3,6);
        op_xyz_pts = plot3(real(op_points),imag(op_points),[0:length(op_points)-1]);
        hold on
        surf([0 0 ],[-1.1 1.1],[-1 length(op_points); -1 length(op_points)],'FaceAlpha',0.2)
        surf([-1.1 1.1], [ 0 0 ],[ length(op_points) length(op_points); -1 -1],'FaceAlpha',0.2)
        xlabel('X')
        ylabel('Y')
        zlabel('Samples')
        
        xlim([-1 1]);
        ylim([-1 1]);
        zlim([0 buf_len])
        set(gca,'CameraUpVector', [0 1 0 ])
        grid on
        
        text_samps = annotation('textbox','position',[.0500    0.48    0.85    0.05],'LineStyle','none','FontSize',10);
        op_text_samps = annotation('textbox','position',[.0500    0    0.85    0.05],'LineStyle','none','FontSize',10);
        diff_equ_text = annotation('textbox',...
                [0.34 0.337941628264209 0.285237188872621 0.0844854070660522],...
                'String',[''],...
                'FontSize',14,...
                'FitBoxToText','off',...
                'EdgeColor','none');
         annotation('textbox',...
                [0.34 0.2 0.285237188872621 0.0844854070660522],...
                'String',['Zero Locations:'],...
                'FontSize',14,...
                'FitBoxToText','off',...
                'EdgeColor','none');
        zero_locations =  uicontrol('style','edit','units','normalized','FontSize',14,'position',  [0.34  0.17 0.2 0.05]);
        update_button =  uicontrol('style','pushbutton', 'string','update locations','units','normalized','position',[0.34  0.12 0.2 0.05],'callback',{@negfgui});

        negfgui('update_freq_response')
    case 'update_freq_response'
        
        b = poly(zero_vals);
        a = poly(pole_vals);
        H = freqz(b,a,fft_len,'whole');
        gain = max(abs(H));
        freq_resp_pts.YData= fftshift(abs(H)/gain); %ensure max gain is 1
        b = b/gain;
        subplot(2,3,4)
        zplane(b,a);
        title('Pole-Zero Plot')
        try
            str = create_difference_equation(b,1,'tex');
            diff_equ_text.String = {['Difference Equation:'], str};
            
        catch
            diff_equ_text.String = {['b coefficients: ' num2str(b)], ['a coefficients:' num2str(a)]};
        end
        
        zero_locations.String = num2str(zero_vals);
        
        
    case 'draw'
        
        set(gcf,'userdata','')
        set(gcf,'windowbuttonmotionfcn','set(gcf,''userdata'',''motion'')')
        set(gcf,'windowbuttonupfcn','set(gcf,''userdata'',''up'')')
        
        done = 0;
       
         while ~done
            waitfor(gcf,'userdata')
            switch get(gcf,'userdata')
                case 'motion'
              
                    pt = get(draw_plt,'currentpoint');
                    if(abs(pt(1,1))>1)
                        pt(1,1) = 1*sign(pt(1,1));
                    end
                    if(abs(pt(1,2))>1)
                        pt(1,2) = 1*sign(pt(1,2));
                    end
                    points(ptr) = pt(1,1)+pt(1,2)*j;
                    xyz_pts.XData(ptr) = real(points(ptr));
                    xyz_pts.YData(ptr) = imag(points(ptr));
                    
                    %filter the signal (it's not perfect!)
                    try
                        op_points(ptr) = 0;
                        for k= 1:length(b)
                            op_points(ptr) = op_points(ptr)+ b(k)*points(ptr-k+1);
                        end
                    catch
                        
                    end
                    
                    op_xyz_pts.XData(ptr) = real(op_points(ptr));
                    op_xyz_pts.YData(ptr) = imag(op_points(ptr));
                    if(ptr>buf_len)
                         disp_plt.ZLim = [ptr-buf_len ptr];
                         op_disp_plt.ZLim = [ptr-buf_len ptr];
                         freq_pts.YData = abs(fftshift(fft(points(ptr-buf_len+1:ptr).*win_func', fft_len)));
                         op_freq_pts.YData = abs(fftshift(fft(op_points(ptr-buf_len+1:ptr).*win_func', fft_len)));
                    end
                    
                    for m =1:tail_len
                        try
                            xy_pts(m).XData(1) = real(points(ptr-m+1));
                            xy_pts(m).YData(1) = imag(points(ptr-m+1));

                            text_samps.String = num2str(fliplr(round(points(ptr-m+1:ptr)*100)/100));
                            op_text_samps.String = num2str(fliplr(round(op_points(ptr-m+1:ptr)*100)/100));
                        catch
                            
                            text_samps.String = num2str(fliplr(round(points(1:ptr)/100)*100));
                        end
                    end
                    
                    ptr=ptr+1;
                    if(ptr> max_points)
                       negfgui('init') 
                    end
                case 'up'
                    done = 1;
            end
            set(gcf,'userdata','')
        end
        set(gcf,'windowbuttonmotionfcn','')
        set(gcf,'windowbuttonupfcn','')

end

        


  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: