WELCHPARSE Parser for the PWELCH & SPECTROGRAM functions Outputs: X - First input signal (used when esttype = MS & PSD) M - An integer containing the length of the data to be segmented isreal_x - Boolean for input complexity Y - Second input signal (used when esttype = CPSD, TFE, MSCOHERE) Ly - Length of second input signal (used when esttype = CPSD, TFE, MSCOHERE) WIN - A scalar or vector containing the length of the window or the window respectively (Note that the length of the window determines the length of the segments) WINNAME - String with the window name. WINPARAM - Window parameter. NOVERLAP - An integer containing the number of samples to overlap (may be empty) K - Number of segments OPTIONS - A structure with the following fields: OPTIONS.nfft - number of freq. points at which the psd is estimated OPTIONS.Fs - sampling freq. if any OPTIONS.range - 'onesided' or 'twosided' psd Direct copy from MATLAB M Hewitson 08-05-08 $Id: welchparse.m,v 1.2 2008/08/01 13:19:43 ingo Exp $
0001 % WELCHPARSE Parser for the PWELCH & SPECTROGRAM functions 0002 % 0003 % Outputs: 0004 % X - First input signal (used when esttype = MS & PSD) 0005 % M - An integer containing the length of the data to be segmented 0006 % isreal_x - Boolean for input complexity 0007 % Y - Second input signal (used when esttype = CPSD, TFE, MSCOHERE) 0008 % Ly - Length of second input signal (used when esttype = CPSD, TFE, MSCOHERE) 0009 % WIN - A scalar or vector containing the length of the window or the 0010 % window respectively (Note that the length of the window determines 0011 % the length of the segments) 0012 % WINNAME - String with the window name. 0013 % WINPARAM - Window parameter. 0014 % NOVERLAP - An integer containing the number of samples to overlap (may 0015 % be empty) 0016 % K - Number of segments 0017 % OPTIONS - A structure with the following fields: 0018 % OPTIONS.nfft - number of freq. points at which the psd is estimated 0019 % OPTIONS.Fs - sampling freq. if any 0020 % OPTIONS.range - 'onesided' or 'twosided' psd 0021 % 0022 % Direct copy from MATLAB 0023 % 0024 % M Hewitson 08-05-08 0025 % 0026 % $Id: welchparse.m,v 1.2 2008/08/01 13:19:43 ingo Exp $ 0027 % 0028 0029 % Author(s): P. Costa 0030 % Copyright 1988-2006 The MathWorks, Inc. 0031 % $Revision: 1.2 $ $Date: 2008/08/01 13:19:43 $ 0032 0033 function [x,M,isreal_x,y,Ly,win,winName,winParam,noverlap,k,L,options] = ... 0034 welchparse(x,esttype,varargin) 0035 0036 % Parse input arguments. 0037 [x,M,isreal_x,y,Ly,win,winName,winParam,noverlap,opts,errid,errmsg] = ... 0038 parse_inputs(x,esttype,varargin{:}); 0039 if ~isempty(errmsg), error(errid,errmsg); end 0040 0041 % Obtain the necessary information to segment x and y. 0042 [L,noverlap,win,errid,errmsg] = segment_info(M,win,noverlap); 0043 if ~isempty(errmsg), error(errid,errmsg); end 0044 0045 % Parse optional args nfft, fs, and spectrumType. 0046 [options,msg] = welch_options(isreal_x,L,opts{:}); 0047 if ~isempty(msg), error(generatemsgid('InvalidParam'),msg); end 0048 0049 % Compute the number of segments 0050 k = (M-noverlap)./(L-noverlap); 0051 0052 % Uncomment the following line to produce a warning each time the data 0053 % segmentation does not produce an integer number of segements. 0054 %if fix(k) ~= k), 0055 % warning(generatemsgid('MustBeInteger'),'The number of segments is not an integer, truncating data.'); 0056 %end 0057 0058 k = fix(k); 0059 end 0060 0061 %----------------------------------------------------------------------------------------------- 0062 function [x,Lx,isreal_x,y,Ly,win,winName,winParam,noverlap,opts,errid,errmsg] = ... 0063 parse_inputs(x,esttype,varargin) 0064 % Parse the inputs to the welch function. 0065 0066 % Assign defaults in case of early return. 0067 isreal_x = 1; 0068 y = []; 0069 Ly = 0; 0070 is2sig = false; 0071 win = []; 0072 winName = 'User Defined'; 0073 winParam = ''; 0074 noverlap = []; 0075 opts = {}; 0076 errid = ''; 0077 errmsg = ''; 0078 0079 % Determine if one or two signal vectors was specified. 0080 Lx = length(x); 0081 if iscell(x), 0082 if Lx > 1, % Cell array. 0083 y = x{2}; 0084 is2sig = true; 0085 end 0086 x = x{1}; 0087 Lx = length(x); 0088 else 0089 if ~any(strcmpi(esttype,{'psd','ms'})), 0090 errid = generatemsgid('invalidSignalVectors'); 0091 errmsg = 'You must specify a cell array with two signal vectors to estimate either the cross power spectral density or the transfer function.'; 0092 return; 0093 end 0094 end 0095 0096 x = x(:); 0097 isreal_x = isreal(x); 0098 0099 % Parse 2nd input signal vector. 0100 if is2sig, 0101 y = y(:); 0102 isreal_x = isreal(y) && isreal_x; 0103 Ly = length(y); 0104 if Ly ~= Lx, 0105 errid = generatemsgid('invalidSignalVectors'); 0106 errmsg = 'The length of the two input vectors must be equal to calculate the cross spectral density.'; 0107 return; 0108 end 0109 end 0110 0111 % Parse window and overlap, and cache remaining inputs. 0112 lenargin = length(varargin); 0113 if lenargin >= 1, 0114 win = varargin{1}; 0115 if lenargin >= 2, 0116 noverlap = varargin{2}; 0117 0118 % Cache optional args nfft, fs, and spectrumType. 0119 if lenargin >= 3, opts = varargin(3:end); end 0120 end 0121 end 0122 0123 if isempty(win) | isscalar(win), 0124 winName = 'hamming'; 0125 winParam = 'symmetric'; 0126 end 0127 0128 end 0129 0130 %----------------------------------------------------------------------------------------------- 0131 %SEGMENT_INFO Determine the information necessary to segment the input data. 0132 % 0133 % Inputs: 0134 % M - An integer containing the length of the data to be segmented 0135 % WIN - A scalar or vector containing the length of the window or the window respectively 0136 % (Note that the length of the window determines the length of the segments) 0137 % NOVERLAP - An integer containing the number of samples to overlap (may be empty) 0138 % 0139 % Outputs: 0140 % L - An integer containing the length of the segments 0141 % NOVERLAP - An integer containing the number of samples to overlap 0142 % WIN - A vector containing the window to be applied to each section 0143 % ERRID - A string containing possible error identifier 0144 % ERRMSG - A string containing possible error messages 0145 % 0146 % 0147 % The key to this function is the following equation: 0148 % 0149 % K = (M-NOVERLAP)/(L-NOVERLAP) 0150 % 0151 % where 0152 % 0153 % K - Number of segments 0154 % M - Length of the input data X 0155 % NOVERLAP - Desired overlap 0156 % L - Length of the segments 0157 % 0158 % The segmentation of X is based on the fact that we always know M and two of the set 0159 % {K,NOVERLAP,L}, hence determining the unknown quantity is trivial from the above 0160 % formula. 0161 0162 function [L,noverlap,win,errid,errmsg] = segment_info(M,win,noverlap) 0163 0164 % Initialize outputs 0165 L = []; 0166 errid = ''; 0167 errmsg = ''; 0168 0169 % Check that noverlap is a scalar 0170 if any(size(noverlap) > 1), 0171 errid = generatemsgid('invalidNoverlap'); 0172 errmsg = 'You must specify an integer number of samples to overlap.'; 0173 return; 0174 end 0175 0176 if isempty(win), 0177 % Use 8 sections, determine their length 0178 if isempty(noverlap), 0179 % Use 50% overlap 0180 L = fix(M./4.5); 0181 noverlap = fix(0.5.*L); 0182 else 0183 L = fix((M+7.*noverlap)./8); 0184 end 0185 % Use a default window 0186 win = hamming(L); 0187 else 0188 % Determine the window and its length (equal to the length of the segments) 0189 if ~any(size(win) <= 1) | ischar(win), 0190 errid = generatemsgid('invalidWindow'); 0191 errmsg = 'The WINDOW argument must be a vector or a scalar.'; 0192 return 0193 elseif length(win) > 1, 0194 % WIN is a vector 0195 L = length(win); 0196 elseif length(win) == 1, 0197 L = win; 0198 win = hamming(win); 0199 end 0200 if isempty(noverlap), 0201 % Use 50% overlap 0202 noverlap = fix(0.5.*L); 0203 end 0204 end 0205 0206 % Do some argument validation 0207 if L > M, 0208 errid = generatemsgid('invalidSegmentLength'); 0209 errmsg = 'The length of the segments cannot be greater than the length of the input signal.'; 0210 return; 0211 end 0212 0213 if noverlap >= L, 0214 errid = generatemsgid('invalidNoverlap'); 0215 errmsg = 'The number of samples to overlap must be less than the length of the segments.'; 0216 return; 0217 end 0218 end 0219 0220 %------------------------------------------------------------------------------ 0221 %WELCH_OPTIONS Parse the optional inputs to the PWELCH function. 0222 % WELCH_OPTIONS returns a structure, OPTIONS, with following fields: 0223 % 0224 % options.nfft - number of freq. points at which the psd is estimated 0225 % options.Fs - sampling freq. if any 0226 % options.range - 'onesided' or 'twosided' psd 0227 0228 function [options,msg] = welch_options(isreal_x,N,varargin) 0229 0230 % Generate defaults 0231 options.nfft = max(256,2^nextpow2(N)); 0232 options.Fs = []; % Work in rad/sample 0233 0234 % Determine if frequency vector specified 0235 freqVecSpec = false; 0236 if (length(varargin) > 0 && length(varargin{1}) > 1) 0237 freqVecSpec = true; 0238 end 0239 0240 if isreal_x && ~freqVecSpec, 0241 options.range = 'onesided'; 0242 else 0243 options.range = 'twosided'; 0244 end 0245 msg = ''; 0246 0247 if any(strcmp(varargin, 'whole')) 0248 warning(generatemsgid('invalidRange'), '''whole'' is not a valid range, use ''twosided'' instead.'); 0249 elseif any(strcmp(varargin, 'half')) 0250 warning(generatemsgid('invalidRange'), '''half'' is not a valid range, use ''onesided'' instead.'); 0251 end 0252 0253 [options,msg] = psdoptions(isreal_x,options,varargin{:}); 0254 0255 end 0256