annotate matlab/bmm/carfac/CARFAC_Run_Segment.m @ 611:0fbaf443ec82

Carfac C++ revision 3, indluding more style improvements. The output structs are now classes again, and have separate storage methods for each output structure along with flags in the Run and RunSegment methods to allow for only storing NAPs if desired.
author alexbrandmeyer
date Fri, 17 May 2013 19:52:45 +0000
parents a0869cb1c99b
children
rev   line source
dicklyon@473 1 % Copyright 2012, Google, Inc.
dicklyon@473 2 % Author Richard F. Lyon
dicklyon@473 3 %
dicklyon@473 4 % This Matlab file is part of an implementation of Lyon's cochlear model:
dicklyon@473 5 % "Cascade of Asymmetric Resonators with Fast-Acting Compression"
dicklyon@473 6 % to supplement Lyon's upcoming book "Human and Machine Hearing"
dicklyon@473 7 %
dicklyon@473 8 % Licensed under the Apache License, Version 2.0 (the "License");
dicklyon@473 9 % you may not use this file except in compliance with the License.
dicklyon@473 10 % You may obtain a copy of the License at
dicklyon@473 11 %
dicklyon@473 12 % http://www.apache.org/licenses/LICENSE-2.0
dicklyon@473 13 %
dicklyon@473 14 % Unless required by applicable law or agreed to in writing, software
dicklyon@473 15 % distributed under the License is distributed on an "AS IS" BASIS,
dicklyon@473 16 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dicklyon@473 17 % See the License for the specific language governing permissions and
dicklyon@473 18 % limitations under the License.
dicklyon@473 19
dicklyon@502 20 function [naps, CF, BM, seg_ohc, seg_agc] = CARFAC_Run_Segment(...
dicklyon@502 21 CF, input_waves, open_loop)
dicklyon@502 22 % function [naps, CF, BM, seg_ohc, seg_agc] = CARFAC_Run_Segment(...
dicklyon@502 23 % CF, input_waves, open_loop)
dicklyon@473 24 %
dicklyon@473 25 % This function runs the CARFAC; that is, filters a 1 or more channel
dicklyon@473 26 % sound input segment to make one or more neural activity patterns (naps);
dicklyon@473 27 % it can be called multiple times for successive segments of any length,
dicklyon@473 28 % as long as the returned CF with modified state is passed back in each
dicklyon@473 29 % time.
dicklyon@473 30 %
dicklyon@473 31 % input_waves is a column vector if there's just one audio channel;
dicklyon@473 32 % more generally, it has a row per time sample, a column per audio channel.
dicklyon@473 33 %
dicklyon@473 34 % naps has a row per time sample, a column per filterbank channel, and
dicklyon@473 35 % a layer per audio channel if more than 1.
dicklyon@475 36 % BM is basilar membrane motion (filter outputs before detection).
dicklyon@473 37 %
dicklyon@473 38 % the input_waves are assumed to be sampled at the same rate as the
dicklyon@473 39 % CARFAC is designed for; a resampling may be needed before calling this.
dicklyon@473 40 %
dicklyon@473 41 % The function works as an outer iteration on time, updating all the
dicklyon@473 42 % filters and AGC states concurrently, so that the different channels can
dicklyon@473 43 % interact easily. The inner loops are over filterbank channels, and
dicklyon@473 44 % this level should be kept efficient.
dicklyon@473 45 %
dicklyon@502 46 % seg_ohc seg_agc are optional extra outputs useful for seeing what the
dicklyon@502 47 % ohc nonlinearity and agc are doing; both in terms of extra damping.
dicklyon@473 48
dicklyon@475 49 if nargin < 3
dicklyon@475 50 open_loop = 0;
dicklyon@475 51 end
dicklyon@475 52
dicklyon@475 53 if nargout > 2
dicklyon@475 54 do_BM = 1;
dicklyon@475 55 else
dicklyon@475 56 do_BM = 0;
dicklyon@475 57 end
dicklyon@475 58
dicklyon@473 59 [n_samp, n_ears] = size(input_waves);
dicklyon@473 60
dicklyon@473 61 if n_ears ~= CF.n_ears
dicklyon@473 62 error('bad number of input_waves channels passed to CARFAC_Run')
dicklyon@473 63 end
dicklyon@473 64
dicklyon@473 65 n_ch = CF.n_ch;
dicklyon@473 66 naps = zeros(n_samp, n_ch, n_ears); % allocate space for result
dicklyon@475 67 if do_BM
dicklyon@475 68 BM = zeros(n_samp, n_ch, n_ears);
dicklyon@502 69 seg_ohc = zeros(n_samp, n_ch, n_ears);
dicklyon@502 70 seg_agc = zeros(n_samp, n_ch, n_ears);
dicklyon@475 71 end
dicklyon@473 72
dicklyon@473 73 detects = zeros(n_ch, n_ears);
dicklyon@473 74 for k = 1:n_samp
dicklyon@473 75 % at each time step, possibly handle multiple channels
dicklyon@473 76 for ear = 1:n_ears
dicklyon@502 77
dicklyon@502 78 % This would be cleaner if we could just get and use a reference to
dicklyon@502 79 % CF.ears(ear), but Matlab doesn't work that way...
dicklyon@502 80
dicklyon@500 81 [car_out, CF.ears(ear).CAR_state] = CARFAC_CAR_Step( ...
dicklyon@500 82 input_waves(k, ear), CF.ears(ear).CAR_coeffs, CF.ears(ear).CAR_state);
dicklyon@473 83
dicklyon@473 84 % update IHC state & output on every time step, too
dicklyon@500 85 [ihc_out, CF.ears(ear).IHC_state] = CARFAC_IHC_Step( ...
dicklyon@500 86 car_out, CF.ears(ear).IHC_coeffs, CF.ears(ear).IHC_state);
dicklyon@473 87
dicklyon@498 88 % run the AGC update step, decimating internally,
dicklyon@500 89 [CF.ears(ear).AGC_state, updated] = CARFAC_AGC_Step( ...
dicklyon@504 90 ihc_out, CF.ears(ear).AGC_coeffs, CF.ears(ear).AGC_state);
dicklyon@498 91
dicklyon@498 92 % save some output data:
dicklyon@498 93 naps(k, :, ear) = ihc_out; % output to neural activity pattern
dicklyon@475 94 if do_BM
dicklyon@475 95 BM(k, :, ear) = car_out;
dicklyon@502 96 state = CF.ears(ear).CAR_state;
dicklyon@502 97 seg_ohc(k, :, ear) = state.zA_memory;
dicklyon@502 98 seg_agc(k, :, ear) = state.zB_memory;;
dicklyon@475 99 end
dicklyon@473 100 end
dicklyon@473 101
dicklyon@498 102 % connect the feedback from AGC_state to CAR_state when it updates;
dicklyon@498 103 % all ears together here due to mixing across them:
dicklyon@498 104 if updated
dicklyon@498 105 if n_ears > 1
dicklyon@498 106 % do multi-aural cross-coupling:
dicklyon@500 107 CF.ears = CARFAC_Cross_Couple(CF.ears);
dicklyon@498 108 end
dicklyon@498 109 if ~open_loop
dicklyon@498 110 CF = CARFAC_Close_AGC_Loop(CF);
dicklyon@498 111 end
dicklyon@473 112 end
dicklyon@473 113 end
dicklyon@473 114