📄 fdutil.m
字号:
sb2 = fdspec('style','edit','position',10,'tag','sb2','format',fstr,...
'help','fdobjhelp');
sb3 = fdspec('style','edit','position',11,'tag','sb3','format',fstr,...
'help','fdobjhelp');
pbm1 = fdmeas('style','edit','position',5,'tag','pbm1','format',fstr,...
'help','fdobjhelp');
pbm2 = fdmeas('style','edit','position',6,'tag','pbm2','format',fstr,...
'help','fdobjhelp');
pbm3 = fdmeas('style','edit','position',7,'tag','pbm3','format',fstr,...
'help','fdobjhelp');
sbm1 = fdmeas('style','edit','position',9,'tag','sbm1','format',fstr,...
'help','fdobjhelp');
sbm2 = fdmeas('style','edit','position',10,'tag','sbm2','format',fstr,...
'help','fdobjhelp');
sbm3 = fdmeas('style','edit','position',11,'tag','sbm3','format',fstr,...
'help','fdobjhelp');
ax = fdax('tag','ax','title','Frequency Response',...
'xlabel','Frequency',...
'ylabel','Magnitude (dB)',...
'help','fdobjhelp');
co = get(0,'defaultaxescolororder');
lo = get(0,'defaultaxeslinestyleorder');
% response line needs to be at bottom of stacking order:
Lresp = fdline('tag','response','erasemode','normal','color',co(1,:),...
'help','fdobjhelp');
L1 = fdline('tag','passband','color',co(min(3,size(co,1)),:),...
'linewidth',2,...
'help','fdobjhelp');
L2 = fdline('tag','stopband','color',co(min(3,size(co,1)),:),...
'linewidth',2,...
'help','fdobjhelp');
L3_1 = fdline('xdata',[0 0],'ydata',[-1000 1000],...
'tag','L3_1',...
'visible','off',...
'erasemode','xor',...
'affectlimits','off',...
'segmentdragmode',{'lr'},...
'segmentpointer',{'lrdrag'},...
'color',co(min(2,size(co,1)),:),...
'help','fdobjhelp');
L3_2 = fdline('xdata',[0 0],'ydata',[-1000 1000],...
'tag','L3_2',...
'visible','off',...
'erasemode','xor',...
'affectlimits','off',...
'segmentdragmode',{'lr'},...
'segmentpointer',{'lrdrag'},...
'color',co(min(2,size(co,1)),:),...
'help','fdobjhelp');
end
pbspecs = [pb1; pb2; pb3];
sbspecs = [sb1; sb2; sb3];
pbmeasures = [pbm1; pbm2; pbm3];
sbmeasures = [sbm1; sbm2; sbm3];
function changeToText(obj)
% changes FDSPEC or FDMEAS object's style to text
% sets position in case new style has different positioning
% (which is the case when coming from edit on the Mac)
bgcolor = get(0,'defaultuicontrolbackgroundcolor');
for i = 1:length(obj)
set(obj(i),'style','text',...
'backgroundcolor',bgcolor)
set(obj(i),'position',obj(i).position)
end
function changeToEdit(obj)
% changes FDSPEC or FDMEAS object's style to edit
% sets position in case new style has different positioning
% (which is the case when coming from text on the Mac)
for i = 1:length(obj)
set(obj(i),'style','edit',...
'backgroundcolor','w')
set(obj(i),'position',obj(i).position)
end
function xlim = xlimpassband(type,Fs,f1,f2,f3,f4)
% returns passband xlimits
switch type
case 1 % lowpass
xlim = [0 f1];
case 2 % highpass
xlim = [f2 Fs/2];
case 3 % bandpass
xlim = [f2 f3];
case 4
xlim = [0 Fs/2];
end
dxl = (xlim(2)-xlim(1))*.1;
xlim = inbounds(xlim+[-dxl/2 dxl/2],[0 Fs/2]);
function [ind,peaks] = findpeaks(y)
% FINDPEAKS Find peaks in real vector.
% ind = findpeaks(y) finds the indices (ind) which are
% local maxima in the sequence y.
%
% [ind,peaks] = findpeaks(y) returns the value of the peaks at
% these locations, i.e. peaks=y(ind);
y = y(:)';
switch length(y)
case 0
ind = [];
case 1
ind = 1;
otherwise
dy = diff(y);
not_plateau_ind = find(dy~=0);
ind = find( ([dy(not_plateau_ind) 0]<0) & ([0 dy(not_plateau_ind)]>0) );
ind = not_plateau_ind(ind);
if y(1)>y(2)
ind = [1 ind];
end
if y(end-1)<y(end)
ind = [ind length(y)];
end
end
if nargout > 1
peaks = y(ind);
end
function updateRanges(freq_ind,f1,f2,f3,f4)
% update ranges of frequency objects
% Inputs:
% freq_ind - vector of indices of frequencies that have changed
% f1,f2,f3,f4 - fdspec or fdmeas objects
for i = 1:length(freq_ind)
switch freq_ind(i)
case 1
r = get(f2,'range');
set(f2,'range',[get(f1,'value') r(2)])
case 2
r = get(f1,'range');
set(f1,'range',[r(1) get(f2,'value')])
r = get(f3,'range');
set(f3,'range',[get(f2,'value') r(2)])
case 3
r = get(f2,'range');
set(f2,'range',[r(1) get(f3,'value')])
r = get( f4,'range');
set(f4,'range',[get(f3,'value') r(2)])
case 4
r = get(f3,'range');
set(f3,'range',[r(1) get(f4,'value')])
end
end
function [continueFlag,str] = largeWarning(n,msg)
% If msg = 'motion' or 'up':
% return an error string that the filter order is too large
% If msg = anything else:
% issue a warning that filter order is very large
% and prompt user if they really want to do this
str = { [num2str(n) ' is a very large filter order for']
'this type of filter. This may take a very long time'
'and/or cause unpredictable results. Are you sure you'
'want to design this filter?'};
if any(strcmp(msg,{'motion', 'up'}))
continueFlag = 0;
str = ['Filter order ' num2str(n) ' too large for this type of filter.'];
else
ans = questdlg(str,'Large Filter Order','Yes','No','No');
continueFlag = strcmp(ans,'Yes');
str = ['Filter order ' num2str(n) ' too large for this type of filter.'];
end
function [xd1,xd2] = validateBands(xd1,xd2,type,f_ind,f,f1,f2,f3,f4,Fs)
% Function which makes sure frequency bands are legal, and fixes them if not
% Inputs:
% xd1, xd2 - xdata of passband (xd1) and stopband (xd2) lines
% type - filter type, 1=lp,2=hp,3=bp,4=bs
% f_ind - index of frequency which has changed
% f - frequency value vector, unnormalized
% f1,f2,f3,f4 - fdspec or fdmeas objects - their values may be
% changed during the execution of this function
% Fs - sampling frequency
if all(diff(f)>0)
return
end
if type < 3
f = f(1:2);
end
fobjs = [f1 f2 f3 f4];
df = f(f_ind) - get(fobjs(f_ind),'lastvalue');
[f,f_ind] = pushedges(f,f_ind,Fs,df);
for ii = 1:length(f_ind)
set(fobjs(f_ind(ii)),'value',f(f_ind(ii)))
end
f = [0 f Fs/2];
switch type
case 1 % lowpass
xd1 = [f(1:2) NaN f(1:2)];
xd2 = f(3:4);
case 2 % highpass
xd1 = [f(3:4) NaN f(3:4)];
xd2 = f(1:2);
case 3 % bandpass
xd1 = [f(3:4) NaN f(3:4)];
xd2 = [f(1:2) NaN f(5:6)];
case 4 % bandstop
xd1 = [f(1:2) NaN f(1:2) NaN f(5:6) NaN f(5:6)];
xd2 = f(3:4);
end
function [f,i] = pushedges(f,i,Fs,df)
% push band edges in frequency vector f, assuming edge i has changed
% Inputs:
% f - 2 or 4 element frequency band edge vector
% i - index of changed element
% Fs - sampling frequency
% df - amount that f(i) has changed (so previous f(i) was f(i)-df)
% Outputs:
% f - new band edges, a row vector
% i - indices of any band edges which have changed
f_old = f(:);
f = [0; f(:); Fs/2];
j = i+1;
sf = sign(df);
N = length(f);
while f(j)>0 & f(j)<Fs/2 & sf ~= 0 % if sf=0 loop becomes infinite
j = j + sf;
if f(min(j,j-sf)) >= f(max(j,j - sf)) % need to push this band edge
f(j) = f(j) + df;
if ~rem(j,2) % j is even - push next band edge as well
% to keep transition band width constant
f(j+sf) = f(j+sf) + df;
end
end
end
if (j>1) & (j<N)
if sf<0
f = [linspace(0,f(i+1),i+1)'; f(i+2:end)];
else
f = [f(1:i); linspace(f(i+1),f(end),N-i)'];
end
end
f = f(2:end-1);
i = sort([i; find(f~=f_old)]);
f = f(:)';
function [H,f] = chirpfreqz(num,den,fstart,fend,Fs,M)
%Compute frequency response of num,den using chirp z-transform
% Inputs:
% num, den - filter coefficients
% fstart, fend - starting and ending frequencies, in Hz
% Fs - sampling frequency, in Hz
% M - number of points
% Outputs:
% H - frequency response
% f - frequencies = linspace(fstart,fend,M)
delta_f = (fend - fstart)/(M-1)*2*pi/Fs;
c = {M exp(-j*delta_f) exp(j*fstart*2*pi/Fs)};
H = czt(num,c{:})./czt(den,c{:});
f = linspace(fstart,fend,M);
function H = dft(num,den,f,Fs)
%Compute frequency response of num,den using dft
% Inputs:
% num, den - filter coefficients
% f - frequency vector, in Hz
% Fs - sampling frequency, in Hz
% Outputs:
% H - frequency response
B = exp(-j*(f(:)*2*pi/Fs)*(0:length(num)-1))*num(:);
A = exp(-j*(f(:)*2*pi/Fs)*(0:length(den)-1))*den(:);
H = B./A;
function filt = updateFiltSpecs(filt)
%Updates filter structure (especially .specs field) from
%version 1.0 to version 2.0
switch filt.specs.type
case 1
end
function [val,errstr] = fdvalidstr(str,complex,integer,range,inclusive);
% Check to see if string is valid given certain constraints.
% Inputs:
% str - string as entered by user into edit box
% complex - may the number entered be complex? boolean, 1=true, 0=false
% integer - must the string be an integer? boolean
% range - 2 element real, range(1)<range(2), specifies interval for valid
% values of val
% inclusive - 2 element boolean vector, specifies whether min and max
% in range argument are allowed as values
% Outputs:
% val - numerical value of entered string, = [] if errstr is not empty
% errstr - '' if value is valid, otherwise contains brief description
% of why the str is bad.
warnsave = warning;
warning('off') % turn off in case entry is empty or issues a warning
val = evalin('base',str,'[]');
validVal = 1;
errstr = '';
if all(size(val)==1)
if ~complex & val~=real(val)
validVal = 0;
errstr = 'Sorry, this value must be real.';
end
if validVal & (integer & val~=round(val))
validVal = 0;
errstr = 'Sorry, this value must be an integer.';
end
if validVal & inclusive(1)
validVal = validVal * (val>=range(1));
if ~validVal
errstr = rangeErrStr(range,inclusive);
end
elseif validVal & ~inclusive(1)
validVal = validVal * (val>range(1));
if ~validVal
errstr = rangeErrStr(range,inclusive);
end
end
if validVal & inclusive(2)
validVal = validVal * (val<=range(2));
if ~validVal
errstr = rangeErrStr(range,inclusive);
end
elseif validVal & ~inclusive(2)
validVal = validVal * (val<range(2));
if ~validVal
errstr = rangeErrStr(range,inclusive);
end
end
else
validVal = 0;
errstr = sprintf(['Sorry, the value you entered either is' ...
' the wrong size (it must be a scalar), or there' ...
' was a problem evaluating it.']);
end
if ~isempty(errstr),
val = [];
end
warning(warnsave)
function errstr = rangeErrStr(range,inclusive)
%rangeErrStr
if all(inclusive == [1 1])
errstr = sprintf('Sorry, this value must be at least %g and at most %g.',...
range(1),range(2));
elseif all(inclusive == [1 0])
errstr = sprintf('Sorry, this value must be at least %g and less than %g.',...
range(1),range(2));
elseif all(inclusive == [0 1])
errstr = sprintf('Sorry, this value must be greater than %g and at most %g.',...
range(1),range(2));
elseif all(inclusive == [0 0])
errstr = sprintf('Sorry, this value must be greater than %g and less than %g.',...
range(1),range(2));
else
error('inclusive value not set correctly')
end
function setLines(module,L1,L2,setOrderFlag,type,f,Fs,...
minpass,maxpass,minstop,dragUpperPassband)
% NOTE: most modules must set setOrderFlag to 0 because it is possible
% to drag L1 and L2 in set order mode
if nargin<11
% this input flag determines whether it is possible to
% drag the upper passband line (desirable in fdkaiser, fdremez,
% and fdfirls, but not for the 4 IIR routines)
dragUpperPassband = 0;
end
switch type
case 1 % lowpass
set(L1,'xdata',[f(1:2) NaN f(1:2)]*Fs/2,...
'ydata',[maxpass maxpass NaN minpass minpass])
if ~setOrderFlag
set(L1,...
'vertexdragmode',{'none' 'lr' 'none' 'none' 'lr'},...
'vertexdragcallback',...
{'' [module '(''L1drag'',1,2)'] '' '' ...
[module '(''L1drag'',1,5)']},...
'vertexpointer',{'' 'lrdrag' '' '' 'lrdrag'})
end
set(L2,'xdata',[f(3:4)]*Fs/2,'ydata',[minstop minstop])
if ~setOrderFlag
set(L2,...
'vertexdragmode',{'lr' 'none'},...
'vertexdragcallback',...
{[module '(''L2drag'',1,1)'] ''},...
'vertexpointer',{'lrdrag' ''})
end
case 2 % highpass
set(L1,'xdata',[f(3:4) NaN f(3:4)]*Fs/2,...
'ydata',[maxpass maxpass NaN minpass minpass ])
if ~setOrderFlag
set(L1,...
'vertexdragmode',{'lr' 'none' 'none' 'lr' 'none'},...
'vertexdragcallback',...
{[module '(''L1drag'',2,1)'] '' '' ...
[module '(''L1drag'',2,4)'] ''},...
'vertexpointer',{'lrdrag' '' '' 'lrdrag' ''})
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -