annotate trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m @ 696:d8a404fbc4df

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