changeset 456:6ddf64b38211

Bug fixes to make binaural work
author dicklyon@google.com
date Thu, 16 Feb 2012 18:34:04 +0000
parents f8ba7ad93fa9
children 80d1790ba33a
files matlab/bmm/carfac/CARFAC_Init.m matlab/bmm/carfac/CARFAC_Run.m matlab/bmm/carfac/CARFAC_SAI.m matlab/bmm/carfac/CARFAC_binaural.m matlab/bmm/carfac/CARFAC_hacking.m matlab/bmm/carfac/ERB_Hz.m
diffstat 6 files changed, 100 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/matlab/bmm/carfac/CARFAC_Init.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/CARFAC_Init.m	Thu Feb 16 18:34:04 2012 +0000
@@ -54,34 +54,28 @@
 for mic = 1:n_mics
   CF_struct.filter_state(mic).z1_memory = zeros(CF_struct.n_ch, 1);
   CF_struct.filter_state(mic).z2_memory = zeros(CF_struct.n_ch, 1);
-  % cubic loop
-  CF_struct.filter_state(mic).zA_memory = zeros(CF_struct.n_ch, 1);
-  % AGC interp
-  CF_struct.filter_state(mic).zB_memory = zeros(CF_struct.n_ch, 1);
-  % AGC incr
-  CF_struct.filter_state(mic).dzB_memory = zeros(CF_struct.n_ch, 1);
+  CF_struct.filter_state(mic).zA_memory = zeros(CF_struct.n_ch, 1);  % cubic loop
+  CF_struct.filter_state(mic).zB_memory = zeros(CF_struct.n_ch, 1);  % AGC interp
+  CF_struct.filter_state(mic).dzB_memory = zeros(CF_struct.n_ch, 1);  % AGC incr
   CF_struct.filter_state(mic).zY_memory = zeros(CF_struct.n_ch, 1);
   CF_struct.filter_state(mic).detect_accum = zeros(CF_struct.n_ch, 1);
   % AGC loop filters' state:
-  % HACK init
-  CF_struct.AGC_state(mic).AGC_memory = zeros(CF_struct.n_ch, n_AGC_stages);
+  CF_struct.AGC_state(mic).AGC_memory = zeros(CF_struct.n_ch, n_AGC_stages);  % HACK init
   CF_struct.AGC_state(mic).AGC_sum = zeros(CF_struct.n_ch, 1);
   % IHC state:
   if CF_struct.IHC_coeffs.just_hwr
     CF_struct.IHC_state(mic).ihc_accum = zeros(CF_struct.n_ch, 1);
   else
     CF_struct.IHC_state(mic).cap_voltage = ...
-      CF_struct.IHC_coeffs(mic).rest_cap * ones(CF_struct.n_ch, 1);
+      CF_struct.IHC_coeffs.rest_cap * ones(CF_struct.n_ch, 1);
     CF_struct.IHC_state(mic).cap1_voltage = ...
-      CF_struct.IHC_coeffs(mic).rest_cap1 * ones(CF_struct.n_ch, 1);
+      CF_struct.IHC_coeffs.rest_cap1 * ones(CF_struct.n_ch, 1);
     CF_struct.IHC_state(mic).cap2_voltage = ...
-      CF_struct.IHC_coeffs(mic).rest_cap2 * ones(CF_struct.n_ch, 1);
+      CF_struct.IHC_coeffs.rest_cap2 * ones(CF_struct.n_ch, 1);
     CF_struct.IHC_state(mic).lpf1_state = ...
-      CF_struct.IHC_coeffs(mic).rest_output * zeros(CF_struct.n_ch, 1);
+      CF_struct.IHC_coeffs.rest_output * zeros(CF_struct.n_ch, 1);
     CF_struct.IHC_state(mic).lpf2_state = ...
-      CF_struct.IHC_coeffs(mic).rest_output * zeros(CF_struct.n_ch, 1);
+      CF_struct.IHC_coeffs.rest_output * zeros(CF_struct.n_ch, 1);
     CF_struct.IHC_state(mic).ihc_accum = zeros(CF_struct.n_ch, 1);
   end
 end
-
-
--- a/matlab/bmm/carfac/CARFAC_Run.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/CARFAC_Run.m	Thu Feb 16 18:34:04 2012 +0000
@@ -140,7 +140,7 @@
         hold on
         plot(agcsum, 'k-')
       end
-      axis([0, CF.n_ch, 0, max(0.001, maxsum)]);
+      axis([0, CF.n_ch, 0, max(0.001, max(maxsum))]);
       drawnow
     end
   end
--- a/matlab/bmm/carfac/CARFAC_SAI.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/CARFAC_SAI.m	Thu Feb 16 18:34:04 2012 +0000
@@ -17,54 +17,68 @@
 % See the License for the specific language governing permissions and
 % limitations under the License.
 
-function [CF, sai] = CARFAC_SAI(CF, k, n_mics, naps, sai)
-% function sai = CARFAC_SAI(CF_struct, n_mics, naps, sai)
+function [sai_frame, sai_state, naps] = CARFAC_SAI(naps, k, sai_state, SAI_params)
+% function sai = CARFAC_SAI(naps, k, sai_state, SAI_params)
 %
-% Calculate the Stabilized Auditory Image from naps
+% Calculate the Stabilized Auditory Image from naps; 
+% I think this is a binaural SAI by Steven Ness
+%
+% k seems to be a time index; it's an incremental update of the images...
+% but this doesn't sound like a proper incremental approach...
 %
 
-  threshold_alpha = CF.sai_params.threshold_alpha;
-  threshold_jump = CF.sai_params.threshold_jump_factor;
-  threshold_offset = CF.sai_params.threshold_jump_offset;
+[n_samp, n_ch, n_mics] = size(naps);
 
-  sai2 = reshape(sai,CF.sai_params.sai_width * CF.n_ch,n_mics);
-  naps2 = reshape(naps,CF.n_samp * CF.n_ch,n_mics);
+if nargin < 4
+  SAI_params = struct( ...
+    'frame_jump', 200, ...
+    'sai_width', 500, ...
+    'threshold_alpha', 0.99, ...
+    'threshold_jump_factor', 1.2, ...
+    'threshold_jump_offset', 0.1};
+end
 
-  for mic = 1:n_mics
-    data = naps(k, :, mic)';
-    above_threshold = (CF.sai_state(mic).lastdata > ...
-                       CF.sai_state(mic).thresholds) & ...
-                      (CF.sai_state(mic).lastdata > data);
-    CF.sai_state(mic).thresholds(above_threshold) = ...
-        data(above_threshold) * threshold_jump + threshold_offset;
-    CF.sai_state(mic).thresholds(~above_threshold) = ...
-        CF.sai_state(mic).thresholds(~above_threshold) * threshold_alpha;
-    CF.sai_state(mic).lastdata = data;
+threshold_alpha = SAI_params.threshold_alpha;
+threshold_jump = SAI_params.threshold_jump_factor;
+threshold_offset = SAI_params.threshold_jump_offset;
 
-    % Update SAI image with strobe data.
-    othermic = 3 - mic;
+sai2 = reshape(sai_state.sai, SAI_params.sai_width * n_ch, n_mics);
+naps2 = reshape(naps, n_samp * n_ch, n_mics);
 
-    % Channels that are above the threhsold
-    above_ch = find(above_threshold);
+for mic = 1:n_mics
+  data = naps(k, :, mic)';
+  above_threshold = (sai_state(mic).lastdata > ...
+    sai_state(mic).thresholds) & ...
+    (sai_state(mic).lastdata > data);
+  sai_state(mic).thresholds(above_threshold) = ...
+    data(above_threshold) * threshold_jump + threshold_offset;
+  sai_state(mic).thresholds(~above_threshold) = ...
+    sai_state(mic).thresholds(~above_threshold) * threshold_alpha;
+  sai_state(mic).lastdata = data;
+  
+  % Update SAI image with strobe data.
+  othermic = 3 - mic;
+  
+  % Channels that are above the threhsold
+  above_ch = find(above_threshold);
+  
+  % If we are above the threshold, set the trigger index and reset the
+  % sai_index
+  sai_state(mic).trigger_index(above_ch) = k;
+  sai_state(mic).sai_index(above_ch) = 1;
+  
+  % Copy the right data from the nap to the sai
+  chans = (1:n_ch)';
+  fromindices = sai_state(mic).trigger_index() + (chans - 1) * n_samp;
+  toindices = min((sai_state(mic).sai_index() + (chans - 1) * sai_params.sai_width), sai_params.sai_width * n_ch);
+  sai2(toindices,mic) = naps2(fromindices, othermic);
+  
+  sai_state(mic).trigger_index(:) = sai_state(mic).trigger_index(:) + 1;
+  sai_state(mic).sai_index(:) = sai_state(mic).sai_index(:) + 1;
+end
 
-    % If we are above the threshold, set the trigger index and reset the
-    % sai_index
-    CF.sai_state(mic).trigger_index(above_ch) = k;
-    CF.sai_state(mic).sai_index(above_ch) = 1;
 
-    % Copy the right data from the nap to the sai
-    chans = (1:CF.n_ch)';
-    fromindices = CF.sai_state(mic).trigger_index() + (chans - 1) * CF.n_samp;
-    toindices = min((CF.sai_state(mic).sai_index() + (chans - 1) * ...
-                     CF.sai_params.sai_width), ...
-                     CF.sai_params.sai_width * CF.n_ch);
-    sai2(toindices,mic) = naps2(fromindices,othermic);
+sai_frame = reshape(sai2,sai_params.sai_width,n_ch,n_mics);
+sai_state.sai = sai;  % probably this is not exactly what we want to store as state...
 
-    CF.sai_state(mic).trigger_index(:) = CF.sai_state(mic).trigger_index(:) + 1;
-    CF.sai_state(mic).sai_index(:) = CF.sai_state(mic).sai_index(:) + 1;
 
-  end
-
-  sai = reshape(sai2,CF.sai_params.sai_width,CF.n_ch,n_mics);
-  naps = reshape(naps2,CF.n_samp, CF.n_ch,n_mics);
-
--- a/matlab/bmm/carfac/CARFAC_binaural.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/CARFAC_binaural.m	Thu Feb 16 18:34:04 2012 +0000
@@ -17,7 +17,7 @@
 % See the License for the specific language governing permissions and
 % limitations under the License.
 
-% Test/demo hacking for audio/hearing/filterbanks/carfac/matlab/ stuff
+% Test/demo hacking for carfac matlab stuff, two-channel (binaural) case
 
 clear variables
 
@@ -25,36 +25,36 @@
 
 tic
 
-%test_signal = wavread('pbav4p-22050.wav');
-test_signal = wavread('plan-twochannel-1ms.wav')
-%test_signal = wavread('binaural.wav')
-%test_signal = test_signal(20000:2);  % trim for a faster test
+file_signal = wavread('plan.wav');
+file_signal = file_signal(9000+(1:15000));  % trim for a faster test
 
+itd_offset = 22;  % about 1 ms
+test_signal = [file_signal((itd_offset+1):end), ...
+               file_signal(1:(end-itd_offset))] / 10;
+             
 CF_struct = CARFAC_Design;  % default design
-cum_k = 0;  % not doing segments, so just count from 0
 
 % Run mono, then stereo test:
 n_mics = 2
 CF_struct = CARFAC_Init(CF_struct, n_mics);
-
-[nap, CF_struct, cum_k, nap_decim] = ...
-    CARFAC_Run(CF_struct, test_signal, cum_k, agc_plot_fig_num);
+  
+[nap, CF_struct, nap_decim] = CARFAC_Run(CF_struct, test_signal, agc_plot_fig_num);
 
 % Display results for 1 or 2 mics:
 for mic = 1:n_mics
   smooth_nap = nap_decim(:, :, mic);
   figure(mic + n_mics)  % Makes figures 2, 3, and 4
   image(63 * ((smooth_nap)' .^ 0.5))
-
+    
   colormap(1 - gray);
 end
 
 toc
 
 % Show resulting data, even though M-Lint complains:
-cum_k
 CF_struct
 CF_struct.filter_state
 CF_struct.AGC_state
 min_max = [min(nap(:)), max(nap(:))]
 min_max_decim = [min(nap_decim(:)), max(nap_decim(:))]
+
--- a/matlab/bmm/carfac/CARFAC_hacking.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/CARFAC_hacking.m	Thu Feb 16 18:34:04 2012 +0000
@@ -28,11 +28,11 @@
 file_signal = file_signal(9300+(1:5000));  % trim for a faster test
 
 % repeat with negated signal to compare responses:
-file_signal = [file_signal; -file_signal];
+% file_signal = [file_signal; -file_signal];
 
 % make a long test signal by repeating at different levels:
 test_signal = [];
-for dB = -60:20:40  % -80:20:60
+for dB = -40:20:0  % -60:20:40  % -80:20:60
   test_signal = [test_signal; file_signal * 10^(dB/20)];
 end
 
@@ -43,7 +43,7 @@
 
 agc_plot_fig_num = 6;
 
-for n_mics = 1  % :2
+for n_mics = 1:2
   CF_struct = CARFAC_Init(CF_struct, n_mics);
 
   [nap, CF_struct, nap_decim] = CARFAC_Run(CF_struct, ...
@@ -51,7 +51,9 @@
 
 %   nap = deskew(nap);  % deskew doesn't make much difference
 
-  MultiScaleSmooth(nap_decim, 10);
+  if n_mics == 1  % because this hack doesn't work for binarual yet
+    MultiScaleSmooth(nap_decim, 10);
+  end
 
 %   nap_decim = nap;
 %   nap_decim = smooth1d(nap_decim, 1);
--- a/matlab/bmm/carfac/ERB_Hz.m	Wed Feb 15 21:26:40 2012 +0000
+++ b/matlab/bmm/carfac/ERB_Hz.m	Thu Feb 16 18:34:04 2012 +0000
@@ -1,3 +1,22 @@
+% Copyright 2012, Google, Inc.
+% 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"
+% to supplement Lyon's upcoming book "Human and Machine Hearing"
+%
+% Licensed under the Apache License, Version 2.0 (the "License");
+% you may not use this file except in compliance with the License.
+% You may obtain a copy of the License at
+%
+%     http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+% See the License for the specific language governing permissions and
+% limitations under the License.
+
 function ERB = ERB_Hz(CF_Hz, ERB_break_freq, ERB_Q)
 % function ERB = ERB_Hz(CF_Hz, ERB_break_freq, ERB_Q)
 %