diff trunk/matlab/bmm/carfac/CARFAC_Run.m @ 534:95a11cca4619

Add CARFAC_Design_Doc.txt, CARFAC_Run_Segment.m, and some renames; rename various variables to be more parallel; clean up init code and such.
author dicklyon@google.com
date Fri, 16 Mar 2012 04:19:24 +0000
parents fb60ea429bb8
children 2964a3b4a00a
line wrap: on
line diff
--- a/trunk/matlab/bmm/carfac/CARFAC_Run.m	Mon Mar 12 06:14:53 2012 +0000
+++ b/trunk/matlab/bmm/carfac/CARFAC_Run.m	Fri Mar 16 04:19:24 2012 +0000
@@ -17,9 +17,9 @@
 % See the License for the specific language governing permissions and
 % limitations under the License.
 
-function [naps, CF, decim_naps] = CARFAC_Run ...
+function [CF, decim_naps, naps] = CARFAC_Run ...
   (CF, input_waves, AGC_plot_fig_num)
-% function [naps, CF, decim_naps] = CARFAC_Run ...
+% function [CF, decim_naps, 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).
@@ -42,94 +42,82 @@
 % filters and AGC states concurrently, so that the different channels can
 % interact easily.  The inner loops are over filterbank channels, and
 % this level should be kept efficient.
-%
-% See other functions for designing and characterizing the CARFAC:
-% CF = CARFAC_Design(fs, CF_filter_params, CF_AGC_params, n_mics)
-% transfns = CARFAC_Transfer_Functions(CF, to_chans, from_chans)
 
-[n_samp, n_mics] = size(input_waves);
+[n_samp, n_ears] = size(input_waves);
 n_ch = CF.n_ch;
 
 if nargin < 3
   AGC_plot_fig_num = 0;
 end
 
-if n_mics ~= CF.n_mics
+if n_ears ~= CF.n_ears
   error('bad number of input_waves channels passed to CARFAC_Run')
 end
 
-naps = zeros(n_samp, n_ch, n_mics);
-decim_k = 0;
-k_NAP_decim = 0;
-NAP_decim = 8;
-if nargout > 2
+
+naps = zeros(n_samp, n_ch, n_ears);
+
+seglen = 16;
+n_segs = ceil(n_samp / seglen);
+
+if nargout > 1
   % make decimated detect output:
-  decim_naps = zeros(ceil(n_samp/NAP_decim), CF.n_ch, CF.n_mics);
+  decim_naps = zeros(n_segs, CF.n_ch, CF.n_ears);
 else
   decim_naps = [];
 end
 
+if nargout > 2
+  % make decimated detect output:
+  naps = zeros(n_samp, CF.n_ch, CF.n_ears);
+else
+  naps = [];
+end
 
-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, 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));
-    
-    detects(:, mic) = ihc_out;  % for input to AGC, and out to SAI
-    
-    naps(k, :, mic) = ihc_out;  % output to neural activity pattern
-    
+for seg_num = 1:n_segs
+  if seg_num == n_segs
+    % The last segement may be short of seglen, but do it anyway:
+    k_range = (seglen*(seg_num - 1) + 1):n_samp;
+  else
+    k_range = seglen*(seg_num - 1) + (1:seglen);
   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);
+  % Process a segment to get a slice of decim_naps, and plot AGC state:
+  [seg_naps, CF] = CARFAC_Run_Segment(CF, input_waves(k_range, :));
+  
+  if ~isempty(naps)
+    for ear = 1:n_ears
+      % Accumulate segment naps to make full naps
+      naps(k_range, :, ear) = seg_naps(:, :, ear);
     end
   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
-    CF = CARFAC_Close_AGC_Loop(CF);
+  if ~isempty(decim_naps)
+    for ear = 1:n_ears
+      decim_naps(seg_num, :, ear) = CF.IHC_state(ear).ihc_accum / seglen;
+      CF.IHC_state(ear).ihc_accum = zeros(n_ch,1);
+    end
   end
   
-  k_AGC = mod(k_AGC + 1, AGC_plot_decim);
-  if AGC_plot_fig_num && k_AGC == 0
+  if AGC_plot_fig_num
     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(:));
+    for ear = 1:n_ears
+      plot(CF.AGC_state(ear).AGC_memory(:, 1), 'k-', 'LineWidth', 1)
+      maxes(ear) = max(CF.AGC_state(ear).AGC_memory(:));
       hold on
       for stage = 1:3;
-        plot(2^(stage-1) * (CF.AGC_state(mic).AGC_memory(:, stage) - ...
-          2 * CF.AGC_state(mic).AGC_memory(:, stage+1)));
+        plot(2^(stage-1) * (CF.AGC_state(ear).AGC_memory(:, stage) - ...
+          2 * CF.AGC_state(ear).AGC_memory(:, stage+1)));
       end
       stage = 4;
-      plot(2^(stage-1) * CF.AGC_state(mic).AGC_memory(:, stage));
+      plot(2^(stage-1) * CF.AGC_state(ear).AGC_memory(:, stage));
     end
-    axis([0, CF.n_ch+1, -0.01, max(maxes) + 0.01]);
+    axis([0, CF.n_ch+1, 0.0, max(maxes) + 0.01]);
     drawnow
   end
-  
+
 end
 
+
+