annotate trunk/matlab/bmm/carfac/CARFAC_CAR_Step.m @ 703:2bd09040ecf0

Better SAI unit tests. Includes a test to compare the output of the Matlab and C++ version which is currently disabled since the outputs are not identical.
author ronw@google.com
date Mon, 01 Jul 2013 19:02:37 +0000
parents 3e2e0ab4f708
children
rev   line source
dicklyon@534 1 % Copyright 2012, Google, Inc.
dicklyon@534 2 % Author: Richard F. Lyon
dicklyon@534 3 %
dicklyon@534 4 % This Matlab file is part of an implementation of Lyon's cochlear model:
dicklyon@534 5 % "Cascade of Asymmetric Resonators with Fast-Acting Compression"
dicklyon@534 6 % to supplement Lyon's upcoming book "Human and Machine Hearing"
dicklyon@534 7 %
dicklyon@534 8 % Licensed under the Apache License, Version 2.0 (the "License");
dicklyon@534 9 % you may not use this file except in compliance with the License.
dicklyon@534 10 % You may obtain a copy of the License at
dicklyon@534 11 %
dicklyon@534 12 % http://www.apache.org/licenses/LICENSE-2.0
dicklyon@534 13 %
dicklyon@534 14 % Unless required by applicable law or agreed to in writing, software
dicklyon@534 15 % distributed under the License is distributed on an "AS IS" BASIS,
dicklyon@534 16 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dicklyon@534 17 % See the License for the specific language governing permissions and
dicklyon@534 18 % limitations under the License.
dicklyon@534 19
dicklyon@565 20 function [car_out, state] = CARFAC_CAR_Step(x_in, CAR_coeffs, state)
dicklyon@534 21 % function [zY, state] = CARFAC_CAR_Step(x_in, CAR_coeffs, state)
dicklyon@534 22 %
dicklyon@534 23 % One sample-time update step for the filter part of the CARFAC.
dicklyon@534 24
dicklyon@534 25 % Most of the update is parallel; finally we ripple inputs at the end.
dicklyon@534 26
dicklyon@565 27
dicklyon@565 28 % do the DOHC stuff:
dicklyon@565 29
dicklyon@565 30 g = state.g_memory + state.dg_memory; % interp g
dicklyon@565 31 zB = state.zB_memory + state.dzB_memory; % AGC interpolation state
dicklyon@565 32 % update the nonlinear function of "velocity", and zA (delay of z2):
dicklyon@534 33 zA = state.zA_memory;
dicklyon@565 34 v = state.z2_memory - zA;
dicklyon@565 35 % nlf = CARFAC_OHC_NLF(v .* widen, CAR_coeffs); % widen v with feedback
dicklyon@565 36 nlf = CARFAC_OHC_NLF(v, CAR_coeffs);
dicklyon@565 37 % zB * nfl is "undamping" delta r:
dicklyon@565 38 r = CAR_coeffs.r1_coeffs + zB .* nlf;
dicklyon@565 39 zA = state.z2_memory;
dicklyon@534 40
dicklyon@534 41
dicklyon@534 42 % now reduce state by r and rotate with the fixed cos/sin coeffs:
dicklyon@534 43 z1 = r .* (CAR_coeffs.a0_coeffs .* state.z1_memory - ...
dicklyon@534 44 CAR_coeffs.c0_coeffs .* state.z2_memory);
dicklyon@534 45 % z1 = z1 + inputs;
dicklyon@534 46 z2 = r .* (CAR_coeffs.c0_coeffs .* state.z1_memory + ...
dicklyon@534 47 CAR_coeffs.a0_coeffs .* state.z2_memory);
dicklyon@534 48
dicklyon@534 49 zY = CAR_coeffs.h_coeffs .* z2; % partial output
dicklyon@534 50
dicklyon@534 51 % Ripple input-output path, instead of parallel, to avoid delay...
dicklyon@534 52 % this is the only part that doesn't get computed "in parallel":
dicklyon@534 53 in_out = x_in;
dicklyon@534 54 for ch = 1:length(zY)
dicklyon@534 55 % could do this here, or later in parallel:
dicklyon@534 56 z1(ch) = z1(ch) + in_out;
dicklyon@534 57 % ripple, saving final channel outputs in zY
dicklyon@534 58 in_out = g(ch) * (in_out + zY(ch));
dicklyon@534 59 zY(ch) = in_out;
dicklyon@534 60 end
dicklyon@534 61
dicklyon@534 62 % put new state back in place of old
dicklyon@565 63 % (z1 is a genuine temp; the others can update by reference in C)
dicklyon@534 64 state.z1_memory = z1;
dicklyon@534 65 state.z2_memory = z2;
dicklyon@534 66 state.zA_memory = zA;
dicklyon@534 67 state.zB_memory = zB;
dicklyon@534 68 state.zY_memory = zY;
dicklyon@534 69 state.g_memory = g;
dicklyon@534 70
dicklyon@565 71 car_out = zY;
dicklyon@565 72
dicklyon@565 73