0001 function hfunc = resonatorBanks(select)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 switch select
0063 case {'reson','reson_r','reson_z'}
0064 hfunc=@reson;
0065 case 'comb'
0066 hfunc=@comb;
0067 case 'partialHanning'
0068 hfunc=@partialHanning;
0069 case 'betaDistribution'
0070 hfunc=@betaDistribution;
0071 otherwise
0072 hfunc=[];
0073 error('Unknown Input');
0074 end
0075 return
0076
0077 function [wvfOut,resonatorFreqs,BList,AList,QList,RList] = reson(wvfIn,params)
0078 disp('Filtering signal(s) through reson filterbank(s)...');
0079
0080 freqLimits = params.freqLimits;
0081
0082 switch(params.resonFreqSpacing)
0083 case 'log2'
0084 numFilters = params.numFilters;
0085 resonatorFreqs = logspace2(log2(freqLimits(1)),log2(freqLimits(2)),numFilters);
0086
0087 case 'linear'
0088 spacingHz = params.spacingHz;
0089 resonatorFreqs = [freqLimits(1):spacingHz:freqLimits(2)];
0090 numFilters = length(resonatorFreqs);
0091
0092 case 'filterQ'
0093 Q = params.numPeriodDecay;
0094 freqIdx = 1;
0095 resonatorFreqs(freqIdx) = freqLimits(1);
0096 while(resonatorFreqs(freqIdx) <= freqLimits(2))
0097 freqIdx = freqIdx + 1;
0098 lastBW = resonatorFreqs(freqIdx-1)./Q;
0099 resonatorFreqs(freqIdx) = resonatorFreqs(freqIdx-1) + params.spacingFactor*lastBW;
0100 end
0101 numFilters = length(resonatorFreqs);
0102
0103 end
0104
0105 if(ismember(params.gainType,{'weighted','prenorm_weighted'}))
0106 gainFunc = str2func(params.gainFunction.method);
0107 params.gainFunction.resonatorFreqs = resonatorFreqs;
0108 gainVector = gainFunc(params.gainFunction);
0109 end
0110
0111 if(~isfield(params,'bw_measurement'))
0112 params.bw_measurement = 'constant';
0113 end
0114
0115 for ibank = 1:size(wvfIn,1)
0116 disp(['channel ' num2str(ibank) ' ']);
0117 for iReson = 1:numFilters
0118
0119 switch(params.bw_measurement)
0120 case 'constant'
0121 bw = params.bandwidth;
0122
0123 case 'halfPowerBandwidth'
0124 if(iReson == numFilters)
0125 percentBw = (resonatorFreqs(iReson) - resonatorFreqs(iReson-1))./resonatorFreqs(iReson-1);
0126 bw = percentBw*resonatorFreqs(iReson);
0127 else
0128 bw = (resonatorFreqs(iReson+1) - resonatorFreqs(iReson));
0129 end
0130
0131 case 'periodBasedDecay'
0132 Q = params.numPeriodDecay;
0133 bw = resonatorFreqs(iReson)./Q;
0134 end
0135
0136 R = 1 - bw./params.Fs*pi;
0137
0138 psi = resonatorFreqs(iReson)./params.Fs*(2*pi);
0139
0140 switch(params.gainType)
0141 case 'constant'
0142 gainFactor = params.gain;
0143 case 'weighted'
0144 gainFactor = gainVector(iReson);
0145 case 'prenorm_weighted'
0146
0147 gainFactor = (1-R^2)/2.*gainVector(iReson);
0148 case 'normalized_response'
0149 switch(params.method)
0150
0151 case 'reson_r'
0152 gainFactor = 1-R;
0153 case 'reson_z'
0154 gainFactor = (1-R^2)/2;
0155 case 'reson'
0156 gainFactor = (1 - R^2)*sin(theta);
0157 end
0158 end
0159
0160
0161
0162
0163 switch(params.method)
0164 case 'reson_z'
0165 B_unscaled = [1 0 -1];
0166 theta = acos((1+R^2)./(2*R).*cos(psi));
0167 case 'reson'
0168 B_unscaled = [1];
0169 theta = acos((2*R)./(1+R^2).*cos(psi));
0170 case 'reson_r'
0171 theta = psi;
0172 B_unscaled = [1 0 -R];
0173 end
0174
0175 realFreq = psi./(2*pi).*params.Fs;
0176 resonatorFreqs(iReson) = realFreq;
0177
0178 B = B_unscaled.*gainFactor;
0179 A = [1 -2*R*cos(theta) R^2];
0180
0181 wvfOut(ibank,iReson,:) = filter(B,A,wvfIn(ibank,:));
0182
0183
0184 BList{iReson} = B;
0185 AList{iReson} = A;
0186 QList(iReson) = resonatorFreqs(iReson)./bw;
0187 RList(iReson) = R;
0188 end
0189 end
0190 return
0191
0192
0193
0194 function [wvfOut,resonatorFreqs,BList,AList,QList] = comb(wvfIn,params)
0195 disp('Filtering signal(s) through comb filterbank(s)...');
0196
0197 freqLimits = params.freqLimits;
0198 numFilters = params.numFilters;
0199 resonatorFreqs = logspace2(log2(freqLimits(1)),log2(freqLimits(2)),numFilters);
0200
0201 tSamps = params.halfEnergyTimeSecs*params.Fs;
0202
0203 resonatorPeriodSecs = 1./resonatorFreqs;
0204 resonatorPeriodSamps = floor(resonatorPeriodSecs*params.Fs);
0205
0206
0207 alpha = 0.5.^(resonatorPeriodSamps./tSamps);
0208
0209 if(strcmp(params.gainType,'weighted'))
0210 gainFunc = str2func(params.gainFunction.method);
0211 params.gainFunction.resonatorFreqs = resonatorFreqs;
0212 gainVector = gainFunc(params.gainFunction);
0213 end
0214
0215 for ibank = 1:size(wvfIn,1)
0216 disp(['channel ' num2str(ibank) ' ']);
0217 for iComb = 1:numFilters
0218 A = [1 zeros(1,resonatorPeriodSamps(iComb)-1) -1*alpha(iComb)];
0219 B = 1-alpha(iComb);
0220
0221 if(strcmp(params.gainType,'weighted'))
0222 B = B.*gainVector(iComb);
0223 end
0224
0225 wvfOut(ibank,iComb,:) = filter(B,A,wvfIn(ibank,:));
0226
0227
0228 BList{iComb} = B;
0229 AList{iComb} = A;
0230 QList(iComb) = NaN;
0231 end
0232 end
0233
0234 return
0235
0236
0237 function gainVector = partialHanning(params)
0238
0239 gainVector = zeros(size(params.resonatorFreqs));
0240 gainVector(find(params.resonatorFreqs >= params.maxFreq)) = params.maxGain;
0241 gainCurveLength = sum(params.resonatorFreqs < params.maxFreq);
0242 hanningCurve = hanning(gainCurveLength*2);
0243 gainVector(find(params.resonatorFreqs < params.maxFreq)) = params.minGain + (params.maxGain-params.minGain).*hanningCurve(1:gainCurveLength);
0244
0245 return
0246
0247 function gainVector = betaDistribution(params)
0248
0249 freqRange = params.resonatorFreqs - min(params.resonatorFreqs);
0250 xvals = freqRange./max(freqRange);
0251 betaDist = betapdf(xvals,params.betaDistribution.alpha,params.betaDistribution.beta);
0252
0253 if(isfield(params.betaDistribution,'flattenAt') && ~isempty(params.betaDistribution.flattenAt))
0254 [smallestDiff,closestFreqIdx] = min(abs(params.resonatorFreqs - params.betaDistribution.flattenAt));
0255 scaleFactor = (params.maxGain - params.minGain)./betaDist(closestFreqIdx);
0256 gainVector = betaDist.*scaleFactor + params.minGain;
0257 gainVector(find(gainVector > params.maxGain)) = params.maxGain;
0258 else
0259 gainVector = betaDist./max(betaDist).*(params.maxGain - params.minGain) + params.minGain;
0260 end
0261
0262 return