Mercurial > hg > aimc
changeset 529:75b33fd139db
Remove extra sample delay in CARFAC_FilterStep.m
author | dicklyon@google.com |
---|---|
date | Sat, 10 Mar 2012 06:22:56 +0000 |
parents | 741187dc780f |
children | fb60ea429bb8 |
files | trunk/matlab/bmm/carfac/CARFAC_FilterStep.m |
diffstat | 1 files changed, 21 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/matlab/bmm/carfac/CARFAC_FilterStep.m Sat Mar 10 05:05:35 2012 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_FilterStep.m Sat Mar 10 06:22:56 2012 +0000 @@ -22,8 +22,7 @@ % % One sample-time update step for the filter part of the CARFAC. -% Use each stage previous Y as input to next: -inputs = [x_in; state.zY_memory(1:(end-1))]; +% Most of the update is parallel; finally we ripple inputs at the end. % Local nonlinearity zA and AGC feedback zB reduce pole radius: zA = state.zA_memory; @@ -39,21 +38,34 @@ % now reduce state by r and rotate with the fixed cos/sin coeffs: z1 = r .* (filter_coeffs.a_coeffs .* state.z1_memory - ... filter_coeffs.c_coeffs .* state.z2_memory); -z1 = z1 + inputs; +% z1 = z1 + inputs; z2 = r .* (filter_coeffs.c_coeffs .* state.z1_memory + ... filter_coeffs.a_coeffs .* state.z2_memory); % update the "velocity" for cubic nonlinearity, into zA: zA = (((state.z2_memory - z2) .* filter_coeffs.velocity_scale) + ... v_offset) .^ 2; -zA = v_damp_max * zA ./ (v2_corner + zA); % make it more like an "essential" nonlinearity +% soft saturation to make it more like an "essential" nonlinearity: +zA = v_damp_max * zA ./ (v2_corner + zA); % Adjust gain for r variation: g = filter_coeffs.g_coeffs; g = g .* (1 + filter_coeffs.gr_coeffs .* (1 - r).^2); -% Get outputs from inputs and new z2 values: -zY = g .* (inputs + filter_coeffs.h_coeffs .* z2); +gh = g .* filter_coeffs.h_coeffs; +zY = gh .* z2; % partial output; still need to ripple in_out +% ripples input-output path instead of parallel, to avoid delay... +% this is the only path that doesn't get computed "in parallel": +in_out = x_in; +for ch = 1:length(zY) + % could do this here, or later in parallel: + z1(ch) = z1(ch) + in_out; + % ripple, saving output in zY + in_out = g(ch) * in_out + zY(ch); + zY(ch) = in_out; +end +% % final parallel step is the effect of inputs on state z1: +% z1 = z1 + [x_in; zY(1:(end-1))]; % put new state back in place of old state.z1_memory = z1; @@ -62,7 +74,7 @@ state.zB_memory = zB; state.zY_memory = zY; -% % accum the straight hwr version for the sake of AGC range: -% hwr_detect = max(0, zY); % detect with HWR -% state.detect_accum = state.detect_accum + hwr_detect; +% accum the straight hwr version in case someone wants it: +hwr_detect = max(0, zY); % detect with HWR +state.detect_accum = state.detect_accum + hwr_detect;