Mercurial > hg > aimc
diff trunk/matlab/bmm/carfac/CARFAC_Run.m @ 523:2b96cb7ea4f7
Major AGC improvements mostly
author | dicklyon@google.com |
---|---|
date | Thu, 01 Mar 2012 19:49:24 +0000 |
parents | aa282a2b61bb |
children | 741187dc780f |
line wrap: on
line diff
--- a/trunk/matlab/bmm/carfac/CARFAC_Run.m Mon Feb 27 21:50:20 2012 +0000 +++ b/trunk/matlab/bmm/carfac/CARFAC_Run.m Thu Mar 01 19:49:24 2012 +0000 @@ -1,5 +1,5 @@ % Copyright 2012, Google, Inc. -% Author: Richard F. Lyon +% Author Richard F. Lyon % % This Matlab file is part of an implementation of Lyon's cochlear model: % "Cascade of Asymmetric Resonators with Fast-Acting Compression" @@ -19,8 +19,8 @@ function [naps, CF, decim_naps] = CARFAC_Run ... (CF, input_waves, AGC_plot_fig_num) -% function [naps, CF, CF.cum_k, decim_naps] = CARFAC_Run ... -% (CF, input_waves, CF.cum_k, AGC_plot_fig_num) +% function [naps, CF, decim_naps] = CARFAC_Run ... +% (CF, input_waves, AGC_plot_fig_num) % This function runs the CARFAC; that is, filters a 1 or more channel % sound input to make one or more neural activity patterns (naps). % @@ -58,91 +58,89 @@ error('bad number of input_waves channels passed to CARFAC_Run') end -% pull coeffs out of struct first, into local vars for convenience -decim = CF.AGC_params.decimation; +% fastest decimated rate determines some interp needed: +decim1 = CF.AGC_params.decimation(1); naps = zeros(n_samp, n_ch, n_mics); +decim_k = 0; +k_NAP_decim = 0; +NAP_decim = 8; if nargout > 2 % make decimated detect output: - decim_naps = zeros(ceil(n_samp/decim), CF.n_ch, CF.n_mics); + decim_naps = zeros(ceil(n_samp/NAP_decim), CF.n_ch, CF.n_mics); else decim_naps = []; end -decim_k = 0; -sum_abs_response = 0; +k_AGC = 0; +AGC_plot_decim = 16; % how often to plot AGC state; TODO: use segments + +detects = zeros(n_ch, n_mics); for k = 1:n_samp - CF.k_mod_decim = mod(CF.k_mod_decim + 1, decim); % global time phase + CF.k_mod_decim = mod(CF.k_mod_decim + 1, decim1); % global time phase + k_NAP_decim = mod(k_NAP_decim + 1, NAP_decim); % phase of decimated nap % at each time step, possibly handle multiple channels for mic = 1:n_mics [filters_out, CF.filter_state(mic)] = CARFAC_FilterStep( ... input_waves(k, mic), CF.filter_coeffs, CF.filter_state(mic)); - + % update IHC state & output on every time step, too [ihc_out, CF.IHC_state(mic)] = CARFAC_IHCStep( ... filters_out, CF.IHC_coeffs, CF.IHC_state(mic)); - -% sum_abs_response = sum_abs_response + abs(filters_out); - + + detects(:, mic) = ihc_out; % for input to AGC, and out to SAI + naps(k, :, mic) = ihc_out; % output to neural activity pattern + end - - % conditionally update all the AGC stages and channels now: - if CF.k_mod_decim == 0 - % just for the plotting option: - decim_k = decim_k + 1; % index of decimated signal for display - if ~isempty(decim_naps) - for mic = 1:n_mics - % this is HWR out of filters, not IHCs - avg_detect = CF.filter_state(mic).detect_accum / decim; - % This HACK is the IHC version: - avg_detect = CF.IHC_state(mic).ihc_accum / decim; % for cochleagram - decim_naps(decim_k, :, mic) = avg_detect; % for cochleagram -% decim_naps(decim_k, :, mic) = sum_abs_response / decim; % HACK for mechanical out ABS -% sum_abs_response(:) = 0; - end + if ~isempty(decim_naps) && (k_NAP_decim == 0) + decim_k = decim_k + 1; % index of decimated NAP + for mic = 1:n_mics + decim_naps(decim_k, :, mic) = CF.IHC_state(mic).ihc_accum / ... + NAP_decim; % for cochleagram + CF.IHC_state(mic).ihc_accum = zeros(n_ch,1); end - - % get the avg_detects to connect filter_state to AGC_state: - avg_detects = zeros(n_ch, n_mics); + end + % run the AGC update step, taking input from IHC_state, decimating + % internally, all mics at once due to mixing across them: + [CF.AGC_state, updated] = ... + CARFAC_AGCStep(CF.AGC_coeffs, detects, CF.AGC_state); + + % connect the feedback from AGC_state to filter_state when it updates + if updated for mic = 1:n_mics -% % mechanical response from filter output through HWR as AGC in: -% avg_detects(:, mic) = CF.filter_state(mic).detect_accum / decim; - CF.filter_state(mic).detect_accum(:) = 0; % zero the detect accumulator - % New HACK, IHC output relative to rest as input to AGC: - avg_detects(:, mic) = CF.IHC_state(mic).ihc_accum / decim; - CF.IHC_state(mic).ihc_accum(:) = 0; % zero the detect accumulator - end - - % run the AGC update step: - CF.AGC_state = CARFAC_AGCStep(CF.AGC_coeffs, avg_detects, CF.AGC_state); - - % connect the feedback from AGC_state to filter_state: - for mic = 1:n_mics - new_damping = CF.AGC_state(mic).sum_AGC; -% max_damping = 0.15; % HACK -% new_damping = min(new_damping, max_damping); + new_damping = CF.AGC_state(mic).AGC_memory(:, 1); % stage 1 result % set the delta needed to get to new_damping: + % TODO: update this to use da and dc instead of dr maybe? CF.filter_state(mic).dzB_memory = ... (new_damping - CF.filter_state(mic).zB_memory) ... - / decim; - end - - if AGC_plot_fig_num - figure(AGC_plot_fig_num); hold off - maxsum = 0; - for mic = 1:n_mics - plot(CF.AGC_state(mic).AGC_memory) - agcsum = sum(CF.AGC_state(mic).AGC_memory, 2); - maxsum(mic) = max(maxsum, max(agcsum)); - hold on - plot(agcsum, 'k-') - end - axis([0, CF.n_ch, 0, max(0.001, max(maxsum))]); - drawnow + / decim1; end end + + k_AGC = mod(k_AGC + 1, AGC_plot_decim); + if AGC_plot_fig_num && k_AGC == 0 + figure(AGC_plot_fig_num); hold off; clf + set(gca, 'Position', [.25, .25, .5, .5]) + + maxsum = 0; + for mic = 1:n_mics + plot(CF.AGC_state(mic).AGC_memory(:, 1), 'k-', 'LineWidth', 1) + maxes(mic) = max(CF.AGC_state(mic).AGC_memory(:)); + hold on + stage1 = 4; % as opposed to stage + for stage = 1:3; + plot(2^(stage1-1) * (CF.AGC_state(mic).AGC_memory(:, stage) - ... + 2 * CF.AGC_state(mic).AGC_memory(:, stage+1))); + end + stage = 4; + plot(2^(stage1-1) * CF.AGC_state(mic).AGC_memory(:, stage)); + end + axis([0, CF.n_ch+1, -0.01, max(maxes) + 0.01]); + drawnow + end + end