Mercurial > hg > aimc
diff trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m @ 615:2b2ef398b557
Add files for making log-lag SAI from CARFAC's NAP output. The file
SAI_RunLayered.m dumps frames to PNG files. The hacking script calls
ffmpeg to assemble them with the soundtrack into a movie.
author | dicklyon@google.com |
---|---|
date | Thu, 09 May 2013 03:48:44 +0000 |
parents | |
children | 2e456754fe20 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/matlab/bmm/carfac/SAI_UpdateBuffers.m Thu May 09 03:48:44 2013 +0000 @@ -0,0 +1,83 @@ +% Copyright 2013, 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 layer_array = SAI_UpdateBuffers(layer_array, seg_naps, seg_num) +% function layer_array = SAI_UpdateBuffers(layer_array, seg_naps, seg_num) +% +% Input/Output: layer_array contains all the coefficients and state for +% the layer of different time scales of SAI; +% we might want to separate these as in CARFAC. +% +% seg_naps is a new segmeent of NAP from the CAR-FAC to shift into the +% first layer. Each subsequent layer gets input off the input end of the +% previous layer, with smoothing and decimation. +% +% The segment index seg_num is used to control sub-sampled updates of +% the larger-scale layers. + +n_layers = length(layer_array); +[seg_len, n_nap_ch] = size(seg_naps); + +% Array of what to shift in to first or next layer. +new_chunk = seg_naps; + +gain = 1.1; % gain from layer to layer; could be layer dependent. + +%% +% Decimate using a 2-3-4-filter and partial differencing emphasize onsets: +kernel = filter([1 1]/2, 1, filter([1 1 1]/3, 1, [1 1 1 1 0 0 0 0]/4)); +kernel = kernel + 2*diff([0, kernel]); +% figure(1) +% plot(kernel) + +%% +for layer = 1:n_layers + [n_lags, n_ch] = size(layer_array(layer).nap_buffer); + if (n_nap_ch ~= n_ch) + error('Wrong number of channels in nap_buffer.'); + end + + interval = layer_array(layer).update_interval; + if (0 == mod(seg_num, interval)) + % Account for 2X decimation and infrequent updates; find number of time + % points to shift in. Tolerate slip of a fraction of a sample. + n_shift = seg_len * interval / (2.0^(layer - 1)); + if layer > 1 + % Add the leftover fraction before floor. + n_shift = n_shift + layer_array(layer).nap_fraction; + layer_array(layer).nap_fraction = n_shift - floor(n_shift); + n_shift = floor(n_shift); + % Grab new stuff from new end (big time indices) of previous layer. + % Take twice as many times as we need, + 5, for decimation, and do + % 343 smoothing to get new points. + new_chunk = ... + layer_array(layer - 1).nap_buffer((end - 2*n_shift - 4):end, :); + new_chunk = filter(kernel, 1, new_chunk); + new_chunk = gain * new_chunk(7:2:end, :); + + end + % Put new stuff in at latest time indices. + layer_array(layer).nap_buffer = ... + [layer_array(layer).nap_buffer((1 + n_shift):end, :); ... + new_chunk]; % this should fit just right if we have n_shift new times. + end +end + +return +