📄 winplt.m
字号:
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 + -