comparison trunk/matlab/bmm/carfac/CARFAC_Transfer_Functions.m @ 533:55c46c01e522

Implement group-delay in CARFAC_Transfer_Functions, and adjust design parameters to make it come out good (with increased min damping in low-f channels)
author dicklyon@google.com
date Mon, 12 Mar 2012 06:14:53 +0000
parents fb60ea429bb8
children 95a11cca4619
comparison
equal deleted inserted replaced
532:9b478420cbe2 533:55c46c01e522
16 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 % See the License for the specific language governing permissions and 17 % See the License for the specific language governing permissions and
18 % limitations under the License. 18 % limitations under the License.
19 19
20 function [complex_transfns_freqs, ... 20 function [complex_transfns_freqs, ...
21 stage_numerators, stage_denominators] = CARFAC_Transfer_Functions( ... 21 stage_numerators, stage_denominators, group_delays] = ...
22 CF, freqs, to_channels, from_channels) 22 CARFAC_Transfer_Functions(CF, freqs, to_channels, from_channels)
23 % function [complex_transfns_freqs, ... 23 % function [complex_transfns_freqs, ...
24 % stage_numerators, stage_denominators] = CARFAC_Transfer_Functions( ... 24 % stage_numerators, stage_denominators, group_delays] = ...
25 % CF, freqs, to_channels, from_channels) 25 % CARFAC_Transfer_Functions(CF, freqs, to_channels, from_channels)
26 %
26 % Return transfer functions as polynomials in z (nums & denoms); 27 % Return transfer functions as polynomials in z (nums & denoms);
27 % And evaluate them at freqs if it's given, to selected output, 28 % And evaluate them at freqs if it's given, to selected output,
28 % optionally from selected starting points (from 0, input, by default). 29 % optionally from selected starting points (from 0, input, by default).
29 % complex_transfns_freqs has a row of complex gains per to_channel. 30 % complex_transfns_freqs has a row of complex gains per to_channel.
30 31
47 z_row = exp((i * 2 * pi / CF.fs) * freqs); % z = exp(sT) 48 z_row = exp((i * 2 * pi / CF.fs) * freqs); % z = exp(sT)
48 gains = Rational_Eval(stage_numerators, stage_denominators, z_row); 49 gains = Rational_Eval(stage_numerators, stage_denominators, z_row);
49 50
50 % Now multiply gains from input to output places; use logs? 51 % Now multiply gains from input to output places; use logs?
51 log_gains = log(gains); 52 log_gains = log(gains);
52 cum_log_gains = cumsum(log_gains); 53 cum_log_gains = cumsum(log_gains); % accum across cascaded stages
53 54
54 % And figure out which cascade products we want: 55 % And figure out which cascade products we want:
55 n_ch = CF.n_ch; 56 n_ch = CF.n_ch;
56 if nargin < 3 57 if nargin < 3
57 to_channels = 1:n_ch; 58 to_channels = 1:n_ch;
69 from_cum = zeros(length(to_channels), length(z_row)); 70 from_cum = zeros(length(to_channels), length(z_row));
70 not_input = from_channels > 0; 71 not_input = from_channels > 0;
71 from_cum(not_input, :) = cum_log_gains(from_channels(not_input), :); 72 from_cum(not_input, :) = cum_log_gains(from_channels(not_input), :);
72 log_transfns = cum_log_gains(to_channels, :) - from_cum; 73 log_transfns = cum_log_gains(to_channels, :) - from_cum;
73 complex_transfns_freqs = exp(log_transfns); 74 complex_transfns_freqs = exp(log_transfns);
75
76 if nargout >= 4
77 phases = imag(log_gains); % no wrapping problem on single stages
78 cum_phases = cumsum(phases); % so no wrapping here either
79 group_delays = -diff(cum_phases')'; % diff across frequencies
80 group_delays = group_delays ./ (2*pi*repmat(diff(freqs), n_ch, 1));
81 end
74 else 82 else
75 % If no freqs are provided, do nothing but return the stage info above: 83 % If no freqs are provided, do nothing but return the stage info above:
76 complex_transfns_freqs = []; 84 complex_transfns_freqs = [];
77 end 85 end
78 86