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 theta = resonatorFreqs(iReson)./params.Fs*(2*pi);
0138
0139 switch(params.gainType)
0140 case 'constant'
0141 gainFactor = params.gain;
0142 case 'weighted'
0143 gainFactor = gainVector(iReson);
0144 case 'prenorm_weighted'
0145
0146 gainFactor = (1-R^2)/2.*gainVector(iReson);
0147 case 'normalized_response'
0148 switch(params.method)
0149
0150 case 'reson_r'
0151 gainFactor = 1-R;
0152 case 'reson_z'
0153 gainFactor = (1-R^2)/2;
0154 case 'reson'
0155 gainFactor = (1 - R^2)*sin(theta);
0156 end
0157 end
0158
0159
0160
0161
0162 switch(params.method)
0163 case 'reson_z'
0164 B_unscaled = [1 0 -1];
0165 psi = acos((2*R)./(1+R^2).*cos(theta));
0166 case 'reson'
0167 B_unscaled = [1];
0168 psi = acos((1+R^2)./(2*R)*cos(theta));
0169 case 'reson_r'
0170 psi = theta;
0171 B_unscaled = [1 0 -R];
0172 end
0173
0174 realFreq = psi./(2*pi).*params.Fs;
0175 resonatorFreqs(iReson) = realFreq;
0176
0177 B = B_unscaled.*gainFactor;
0178 A = [1 -2*R*cos(theta) R^2];
0179
0180 wvfOut(ibank,iReson,:) = filter(B,A,wvfIn(ibank,:));
0181
0182
0183 BList{iReson} = B;
0184 AList{iReson} = A;
0185 QList(iReson) = resonatorFreqs(iReson)./bw;
0186 RList(iReson) = R;
0187 end
0188 end
0189 return
0190
0191
0192
0193 function [wvfOut,resonatorFreqs,BList,AList,QList] = comb(wvfIn,params)
0194 disp('Filtering signal(s) through comb filterbank(s)...');
0195
0196 freqLimits = params.freqLimits;
0197 numFilters = params.numFilters;
0198 resonatorFreqs = logspace2(log2(freqLimits(1)),log2(freqLimits(2)),numFilters);
0199
0200 tSamps = params.halfEnergyTimeSecs*params.Fs;
0201
0202 resonatorPeriodSecs = 1./resonatorFreqs;
0203 resonatorPeriodSamps = floor(resonatorPeriodSecs*params.Fs);
0204
0205
0206 alpha = 0.5.^(resonatorPeriodSamps./tSamps);
0207
0208 if(strcmp(params.gainType,'weighted'))
0209 gainFunc = str2func(params.gainFunction.method);
0210 params.gainFunction.resonatorFreqs = resonatorFreqs;
0211 gainVector = gainFunc(params.gainFunction);
0212 end
0213
0214 for ibank = 1:size(wvfIn,1)
0215 disp(['channel ' num2str(ibank) ' ']);
0216 for iComb = 1:numFilters
0217 A = [1 zeros(1,resonatorPeriodSamps(iComb)-1) -1*alpha(iComb)];
0218 B = 1-alpha(iComb);
0219
0220 if(strcmp(params.gainType,'weighted'))
0221 B = B.*gainVector(iComb);
0222 end
0223
0224 wvfOut(ibank,iComb,:) = filter(B,A,wvfIn(ibank,:));
0225
0226
0227 BList{iComb} = B;
0228 AList{iComb} = A;
0229 QList(iComb) = NaN;
0230 end
0231 end
0232
0233 return
0234
0235
0236 function gainVector = partialHanning(params)
0237
0238 gainVector = zeros(size(params.resonatorFreqs));
0239 gainVector(find(params.resonatorFreqs >= params.maxFreq)) = params.maxGain;
0240 gainCurveLength = sum(params.resonatorFreqs < params.maxFreq);
0241 hanningCurve = hanning(gainCurveLength*2);
0242 gainVector(find(params.resonatorFreqs < params.maxFreq)) = params.minGain + (params.maxGain-params.minGain).*hanningCurve(1:gainCurveLength);
0243
0244 return
0245
0246 function gainVector = betaDistribution(params)
0247
0248 freqRange = params.resonatorFreqs - min(params.resonatorFreqs);
0249 xvals = freqRange./max(freqRange);
0250 betaDist = betapdf(xvals,params.betaDistribution.alpha,params.betaDistribution.beta);
0251
0252 if(isfield(params.betaDistribution,'flattenAt') && ~isempty(params.betaDistribution.flattenAt))
0253 [smallestDiff,closestFreqIdx] = min(abs(params.resonatorFreqs - params.betaDistribution.flattenAt));
0254 scaleFactor = (params.maxGain - params.minGain)./betaDist(closestFreqIdx);
0255 gainVector = betaDist.*scaleFactor + params.minGain;
0256 gainVector(find(gainVector > params.maxGain)) = params.maxGain;
0257 else
0258 gainVector = betaDist./max(betaDist).*(params.maxGain - params.minGain) + params.minGain;
0259 end
0260
0261 return