annotate matlab/bmm/carfac/SAI_UpdateBuffers.m @ 608:fc353426eaad

Better functionization of SAI, and new way to make picture with lag marginal and smoothed history of lag marginal.
author dicklyon@google.com
date Mon, 13 May 2013 21:15:56 +0000
parents ec3a1c74ec54
children b3118c9ed67f
rev   line source
dicklyon@604 1 % Copyright 2013, Google, Inc.
dicklyon@604 2 % Author: Richard F. Lyon
dicklyon@604 3 %
dicklyon@604 4 % This Matlab file is part of an implementation of Lyon's cochlear model:
dicklyon@604 5 % "Cascade of Asymmetric Resonators with Fast-Acting Compression"
dicklyon@604 6 % to supplement Lyon's upcoming book "Human and Machine Hearing"
dicklyon@604 7 %
dicklyon@604 8 % Licensed under the Apache License, Version 2.0 (the "License");
dicklyon@604 9 % you may not use this file except in compliance with the License.
dicklyon@604 10 % You may obtain a copy of the License at
dicklyon@604 11 %
dicklyon@604 12 % http://www.apache.org/licenses/LICENSE-2.0
dicklyon@604 13 %
dicklyon@604 14 % Unless required by applicable law or agreed to in writing, software
dicklyon@604 15 % distributed under the License is distributed on an "AS IS" BASIS,
dicklyon@604 16 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dicklyon@604 17 % See the License for the specific language governing permissions and
dicklyon@604 18 % limitations under the License.
dicklyon@604 19
dicklyon@604 20 function layer_array = SAI_UpdateBuffers(layer_array, seg_naps, seg_num)
dicklyon@604 21 % function layer_array = SAI_UpdateBuffers(layer_array, seg_naps, seg_num)
dicklyon@604 22 %
dicklyon@604 23 % Input/Output: layer_array contains all the coefficients and state for
dicklyon@604 24 % the layer of different time scales of SAI;
dicklyon@604 25 % we might want to separate these as in CARFAC.
dicklyon@604 26 %
dicklyon@604 27 % seg_naps is a new segmeent of NAP from the CAR-FAC to shift into the
dicklyon@604 28 % first layer. Each subsequent layer gets input off the input end of the
dicklyon@604 29 % previous layer, with smoothing and decimation.
dicklyon@604 30 %
dicklyon@604 31 % The segment index seg_num is used to control sub-sampled updates of
dicklyon@604 32 % the larger-scale layers.
dicklyon@604 33
dicklyon@604 34 n_layers = length(layer_array);
dicklyon@604 35 [seg_len, n_nap_ch] = size(seg_naps);
dicklyon@604 36
dicklyon@604 37 % Array of what to shift in to first or next layer.
dicklyon@604 38 new_chunk = seg_naps;
dicklyon@604 39
dicklyon@608 40 gain = 1.05; % gain from layer to layer; could be layer dependent.
dicklyon@604 41
dicklyon@604 42 %%
dicklyon@604 43 % Decimate using a 2-3-4-filter and partial differencing emphasize onsets:
dicklyon@604 44 kernel = filter([1 1]/2, 1, filter([1 1 1]/3, 1, [1 1 1 1 0 0 0 0]/4));
dicklyon@604 45 kernel = kernel + 2*diff([0, kernel]);
dicklyon@604 46 % figure(1)
dicklyon@604 47 % plot(kernel)
dicklyon@604 48
dicklyon@604 49 %%
dicklyon@604 50 for layer = 1:n_layers
dicklyon@604 51 [n_lags, n_ch] = size(layer_array(layer).nap_buffer);
dicklyon@604 52 if (n_nap_ch ~= n_ch)
dicklyon@604 53 error('Wrong number of channels in nap_buffer.');
dicklyon@604 54 end
dicklyon@604 55
dicklyon@604 56 interval = layer_array(layer).update_interval;
dicklyon@604 57 if (0 == mod(seg_num, interval))
dicklyon@604 58 % Account for 2X decimation and infrequent updates; find number of time
dicklyon@604 59 % points to shift in. Tolerate slip of a fraction of a sample.
dicklyon@604 60 n_shift = seg_len * interval / (2.0^(layer - 1));
dicklyon@604 61 if layer > 1
dicklyon@604 62 % Add the leftover fraction before floor.
dicklyon@604 63 n_shift = n_shift + layer_array(layer).nap_fraction;
dicklyon@604 64 layer_array(layer).nap_fraction = n_shift - floor(n_shift);
dicklyon@604 65 n_shift = floor(n_shift);
dicklyon@604 66 % Grab new stuff from new end (big time indices) of previous layer.
dicklyon@604 67 % Take twice as many times as we need, + 5, for decimation, and do
dicklyon@604 68 % 343 smoothing to get new points.
dicklyon@604 69 new_chunk = ...
dicklyon@604 70 layer_array(layer - 1).nap_buffer((end - 2*n_shift - 4):end, :);
dicklyon@604 71 new_chunk = filter(kernel, 1, new_chunk);
dicklyon@604 72 new_chunk = gain * new_chunk(7:2:end, :);
dicklyon@604 73
dicklyon@604 74 end
dicklyon@604 75 % Put new stuff in at latest time indices.
dicklyon@604 76 layer_array(layer).nap_buffer = ...
dicklyon@604 77 [layer_array(layer).nap_buffer((1 + n_shift):end, :); ...
dicklyon@604 78 new_chunk]; % this should fit just right if we have n_shift new times.
dicklyon@604 79 end
dicklyon@604 80 end
dicklyon@604 81
dicklyon@604 82 return
dicklyon@604 83