⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winplt.m

📁 一个很好用的窗函数生成工具
💻 M
📖 第 1 页 / 共 2 页
字号:
if nargin
 gui = length(findobj('name','FFT window shapes')); % true if the GUI is running
 if gui WPh = get(gcf,'user'); end;
end;

switch nargin
case 0,  % no arguments: Create the winplt window
  ylim = [-145,3];
  TRACEc = [0 1 0; 1 0 0; 0 0 1; 1 0 1; 0 1 1; 1 1 0];
  WPh = plt([0 0],zeros(6,2),'FigName','FFT window shapes',...
    'AxisPos',[1 1 1 .9 1 .95 1 1],'Ylim',ylim,'YlimR',3.5+ylim/40,...
    'LabelX','Bin number','Options','-X-Y','Right',4:6,...
    'LabelYr','Time shape                                            ',...
    'LabelY','Frequency shape (dB)','DisTrace',[0 1 1 0 1 1],'TRACEc',TRACEc);
  set(WPh,{'user'},{'--';'--';'--';'--';'--';'--'});
   uicontrol('Style','Text','Units','Norm','Position',[.15 .905 .09 .04],...
             'BackGround',[.75 .75 .75],'string','Window');
  s = [];  t = '';  k = 0;
  while ischar(t)  t=winplt(k,0);  s=[s sprintf('|%02d:  ',k) t];  k=k+1;  end;
  s = s(2:end-7);
  WPh = [WPh;
         uicontrol('Style','Popup','Units','Norm','Position',[.25 .91 .33 .04],...
                   'Value',2,'Callback','winplt(0)','BackGround',[0 1 1],'String',s);
         uicontrol('Style','CheckBox','Units','Norm','Position',[.96 .57 .03 .04],...
                   'Callback','winplt(0)','BackGround',get(gcf,'Color'),'Value',1,'user',1);
         plt('slider',0,'init',[.803 505 130],[1 60 10 1 500],'# of bins','winplt(0)','on',...
                2,[.75 .75 .75; 0 1 1],['%1d';'%4w';'%2d']);
         plt('slider',0,'init',[.603 505 130],[1 10 1 1 10],'Hanning ^#','winplt(0)','on',...
                2,[.75 .75 .75; 0 1 1],['%1d';'%4w';'%2d']);
         plt('slider',0,'init',[.603 505 130],[1 2 1 1 2],' ','winplt(0)','on',...
                1,[.75 .75 .75; 0 1 1],['%3w';'%4w';'%3d']);
         plt('edit','length',0,'string','userwin(points,param)','callbk','winplt(0)',...
             'units','norm','pos',[.23 1.11],'color',[0 1 1]);
         0;
         text(0,0,''); text(0,0,''); text(0,0,''); text(0,0,''); text(0,0,'')];
  set(WPh(TEXTK:TEXTP),'fontsize',8,'units','norm','color',[.8 .8 .8],...;
       {'pos'},{[-.17 1.11]; [.01 .98]; [.01 .945]; [.01 .91]; [.01 .875]});
  text(0,0,'Power corrected','Units','Norm','Position',[1.06 .66],...
       'Color',[.7 .8 .95],'Rotation',90);
  a = get(WPh(LINET),'Parent'); % find right hand axis
  yt = get(a,'ytick');  set(a,'ytick',yt(1:5)); % remove some of the y tick labels
  set(gcf,'user',WPh);  % save handle list
  winplt(0); % plot the default window (Hanning)

case 1, % One argument: Update the plot based on current popup/slider values
  if id<0 winplt(id,0); return; end;
  if ~gui [out1 out2] = winplt(id,0); return; end;
  if get(WPh(POPUPW),'user') set(WPh(POPUPW),'user',0); return; end;
  if id==29 set(WPh(EDITU),'vis','on'); else set(WPh(EDITU),'vis','off'); end;
  sz = 2048;   % number of points to plot for each window
  b = plt('slider',WPh(SLIDEB),'get');  id = get(WPh(POPUPW),'Value')-1;
  plt('slider',WPh(SLIDEH),'set','minmax',[1 b 1 b]);
  plt('cursor',get(get(WPh(1),'parent'),'User'),'set','xlim',[-b b]);
  chkV = get(WPh(CHECKC),'value');  % value of checkbox (power or amplitude corrected)
  chkU = get(WPh(CHECKC),'user');   % user data of checkbox (previous value)
  set(WPh(CHECKC),'user',chkV);     % save value for next time
  t = winplt(id,sz,chkV);           % t = time window
  bins = 2*b;  sz2 = sz/2;  binres = bins/sz;
  h = 20*log10(eps+abs(fft([winplt(id,bins) zeros(1,sz-bins)]))); % freq shape
  h = h-h(1);                   % normalize to bin 0
  x   = binres*(-sz2:sz2-1);
  if chkV ~= chkU  set(WPh(LINET),'x',x,'y',t); return; end; % for change in power factor correction
  y   = [h(sz2+1:sz) h(1:sz2)]; % current frequency trace (rotate h)
  yp  = get(WPh(LINEF),'y');    % previous frequency trace
  tp  = get(WPh(LINET),'y');    % previous time trace
  ypp = get(WPh(LINEFp),'y');   % previous previous frequency trace
  tpp = get(WPh(LINETp),'y');   % previous previous time trace
  uu = get(WPh(LINEF:LINETpp),'user');
  i = int2str(id); u = {['Freq' i]; uu{1}; uu{2}; ['Time' i]; uu{4}; uu{5}};
  set(WPh(LINEF:LINETpp),'x',x,{'y'},{y;yp;ypp;t;tp;tpp},{'user'},u);
  for r6=1:sz2 if h(r6)<-6 break; end; end; % look for 6dB bandwidth
  h = h(1:1+round(.5/binres));  sloss = max(h)-min(h);
  enbw = sz*sum(t.^2)/(sum(t)^2);  ploss = sloss + 10*log10(enbw);
  if sloss < .1 sloss = sloss*1000; su = ' mdB'; else su = ' dB'; end;
  plt('rename',u);
  set(WPh(TEXTS),'string',['scallop loss = '      plt('ftoa','%6w',sloss) su]);
  set(WPh(TEXTR),'string',['frequency res = '     plt('ftoa','%4w',2*(r6-1)*binres) ' bins']);
  set(WPh(TEXTE),'string',['equiv noise BW = '    plt('ftoa','%4w',enbw) ' bins']);
  set(WPh(TEXTP),'string',['worst case PL = '     plt('ftoa','%4w',ploss) ' dB']);

otherwise, % 2,3,or 4 arguments ------------------------------------------------------------
  if ~points  % if # of points is zero, just return the window name in Out1 and the amplitude
              % corrected convolution kernel in Out2
    switch id
      case  0, out1='Boxcar';                     out2=1;
      case  1, out1='Hanning/Rife Vincent';       out2=0;
      case  2, out1='Chebyshev';                  out2={'chebwin',90,'Sidelobe level',[50 150]};
      case  3, out1='Kaiser';                     out2={'kaiser',12.26526,'Beta',[1 30]};
      case  4, out1='Gaussian';                   out2={'gausswin',4.3,'Alpha',[.1 8]};
      case  5, out1='Tukey';                      out2={'tukeywin',.5,'Taper size',[.01 1]};
      case  6, out1='Bartlett';                   out2={'bartlett'};
      case  7, out1='Modified Bartlett-Hanning';  out2={'barthannwin'};
      case  8, out1='Bohman';                     out2={'bohmanwin'};
      case  9, out1='Nuttall';                    out2={'nuttallwin'};
      case 10, out1='Parzen';                     out2={'parzenwin'};
      case 11, out1='Hamming';                    out2=[1, -.428752];
      case 12, out1='Exact Blackman';             out2=[1, -.58201156, .090007307];
      case 13, out1='Blackman';                   out2=[1, -.595238095, .095238095];
      case 14, out1='Blackman (Matlab)';          out2={'blackman','periodic'};
      case 15, out1='Blackman Harris (Matlab)';   out2={'blackmanharris'};
      case 16, out1='Blackman Harris 61dB';       out2=[1, -.54898908, .063135301];
      case 17, out1='Blackman Harris 67dB';       out2=[1, -.58780096, .093589774];
      case 18, out1='Blackman Harris 74dB';       out2=[1, -.61793520, .116766542, -.002275157];
      case 19, out1='B-Harris 92dB (min 4term)';  out2=[1, -.68054355, .196905923, -.016278746];
      case 20, out1='Potter 210';                 out2=[1, -.61129, .11129];
      case 21, out1='Potter 310';                 out2=[1, -.684988, .2027007, -.0177127];
      case 22, out1='FlatTop  (5 term)';          out2=[1,-.965, .645, -.194, .014];
      case 23, out1='FlatTop  41dB (Potter 201)'; out2=[.9990280, -.925752, .35196]; 
      case 24, out1='FlatTop  60dB (Potter 301)'; out2=[.9994484, -.955728, .539289, -.091581]; 
      case 25, out1='FlatTop  85dB (Potter 401)'; out2=[1, -.970179, .653919, -.201947, .017552];
      case 26, out1='FlatTop  98dB (Mennen 501)'; out2=[1, -.98069, .79548, -.41115, .104466 -.0080777];
      case 27, out1='FlatTop 101dB (Mennen 601)'; out2=[1 -.98919 .858 -.56256 .249 -.05994 4.659e-3];
      case 28, out1='FlatTop  (Matlab)';          out2={'flattopwin','periodic'};
      case 29, out1='user';                       out2={'userwin(points,param)',40,'Parameter',[0 200],0};
      case 30, out1=0; % indicates no more IDs
      otherwise k = 0;  t = winplt(k,0);  out1 = 0;  out2 = 0;
                while ischar(t) disp(sprintf('ID %2d: %s',k,t)); k=k+1; t=winplt(k,0); end;
    end;
    return;
  end;
  % here if number of points is non-zero: return the time domain window shape in Out1
  if nargin<3 pwr=0; end; % use amplitude correction if not specified
  if nargin<4 opt=0; end;   % optional window parameter

  [out1 c] = winplt(id,0);  % get convolution kernel
  if gui plt('slider',WPh(SLIDEH),'set','visOFF');
         plt('slider',WPh(SLIDEP),'set','visOFF');
         set(WPh(TEXTK),'string','');
  end;
  if iscell(c) % Here for Matlab computed windows ----------------------------------
    if length(c)>3                              % Here if there is a window parameter
      if gui                                    % Here if gui is active
         plt('slider',WPh(SLIDEP),'set','visON');
         if length(findobj('string',c{3}))                   % if the correct slider is already there
               c{2} = plt('slider',WPh(SLIDEP),'get');       % then just get the current slider value
         else  plt('slider',WPh(SLIDEP),'set','label',c{3}); % Otherwise set the slider parameters
               cc = [c{4} -1e99 1e99];
               plt('slider',WPh(SLIDEP),'set','minmax',cc);
               set(WPh(POPUPW),'user',1);                    % disable callback on the slider call below
               plt('slider',WPh(SLIDEP),'set',c{2});         % and set the slider value to the default
         end;
      elseif opt c{2}=opt; % If no gui use opt from arg list or c{2} if opt not specified
      end;
    end;
    switch length(c)
      case 1, out1 = feval(c{1},points)';        % compute power corrected window (without option)
      case 2, out1 = feval(c{1},points,c{2})';   % compute power corrected window (with periodic option)
      case 4, out1 = feval(c{1},points,c{2})';   % compute power corrected window (with option)
      case 5, if gui fcn = get(WPh(EDITU),'str'); else fcn = c{1}; end;
              fcn = strrep(fcn,'points',int2str(points)); % compute user defined window
              fcn = strrep(fcn,'param',num2str(c{2}));
              p = find(fcn=='(');
              if isempty(p) | ~exist(fcn(1:p(1)-1))  % does the window function exist?
                 fcn = sprintf('zeros(%d,1)',length(get(WPh(LINEF),'x'))); % use zero if not
              end;
              out1 = eval(fcn)';
    end;
    if pwr out1 = out1 * sqrt(points/sum(out1.^2));  % make it power corrected
    else   out1 = out1 * points/sum(out1);           % make it amplitude corrected
    
     end;
  else % here for kernel defined windows ------------------------------------------
    if ~c                                       % RifeVincent windows
      if gui                                    % if gui active, enable slider
          plt('slider',WPh(SLIDEH),'set','visON');
          p = plt('slider',WPh(SLIDEH),'get');  % get number of HANNs
          b = plt('slider',WPh(SLIDEB),'get');  % get number of bins
          if (p>b) p=b; plt('slider',WPh(SLIDEH),'set',p); end;
      else if ~opt opt=1; end;                  % no gui. Get # of HANNs from arg list
           p=opt;                               % and default to 1 if not specified
      end;
      c = zeros(1,p+1);                         % now compute RifeVincent kernel
      warning off;                              % ingore inexact nchoosek
      for k=0:p
        c(k+1) = (-1)^k * nchoosek(2*p,p-k);    % convolution kernel is row 2p
      end;                                      % of Pascal's triangle
      c = c/c(1);                               % normalized kernel for Rife Vincent windows
    end;                                        % end Rife Vincent
    % out1 =  points * real(ifft([c zeros(1,points-2*length(c)+1) fliplr(c(2:end))]));
    x = (0:points-1)/points;
    out1 = 0*x + c(1);
    for k = 2:length(c) % this calculation is equivalent to above ifft
      out1 = out1 + 2*c(k)*cos(2*pi*(k-1)*x);
    end;
    if gui set(WPh(TEXTK),'string',[num2str(c) '   <-- kernel']); end;
    if pwr out1 = out1 / sqrt((sum(2*c.^2)-c(1)^2)); end;
  end; % end if iscell(c)
end;   % end switch nargin
% end function winplt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -