tom@516: % Copyright 2012, Google, Inc. tom@516: % Author: Richard F. Lyon tom@516: % tom@516: % This Matlab file is part of an implementation of Lyon's cochlear model: tom@516: % "Cascade of Asymmetric Resonators with Fast-Acting Compression" tom@516: % to supplement Lyon's upcoming book "Human and Machine Hearing" tom@516: % tom@516: % Licensed under the Apache License, Version 2.0 (the "License"); tom@516: % you may not use this file except in compliance with the License. tom@516: % You may obtain a copy of the License at tom@516: % tom@516: % http://www.apache.org/licenses/LICENSE-2.0 tom@516: % tom@516: % Unless required by applicable law or agreed to in writing, software tom@516: % distributed under the License is distributed on an "AS IS" BASIS, tom@516: % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tom@516: % See the License for the specific language governing permissions and tom@516: % limitations under the License. tom@516: tom@516: function [ihc_out, state] = CARFAC_IHCStep(filters_out, coeffs, state); tom@516: % function [ihc_out, state] = CARFAC_IHCStep(filters_out, coeffs, state); tom@516: % tom@516: % One sample-time update of inner-hair-cell (IHC) model, including the tom@516: % detection nonlinearity and one or two capacitor state variables. tom@516: tom@516: just_hwr = coeffs.just_hwr; tom@516: tom@516: if just_hwr tom@516: ihc_out = max(0, filters_out); tom@516: state.ihc_accum = state.ihc_accum + max(0, ihc_out); tom@516: else tom@516: one_cap = coeffs.one_cap; tom@516: tom@516: detect = CARFAC_Detect(filters_out/2); % detect with HWR or so tom@516: tom@516: if one_cap tom@516: ihc_out = detect .* state.cap_voltage; tom@516: state.cap_voltage = state.cap_voltage - ihc_out .* coeffs.out_rate + ... tom@516: (1 - state.cap_voltage) .* coeffs.in_rate; tom@516: else tom@516: % change to 2-cap version more like Meddis's: tom@516: ihc_out = detect .* state.cap2_voltage; tom@516: state.cap1_voltage = state.cap1_voltage - ... tom@516: (state.cap1_voltage - state.cap2_voltage) .* coeffs.out1_rate + ... tom@516: (1 - state.cap1_voltage) .* coeffs.in1_rate; tom@516: tom@516: state.cap2_voltage = state.cap2_voltage - ihc_out .* coeffs.out2_rate + ... tom@516: (state.cap1_voltage - state.cap2_voltage) .* coeffs.in2_rate; tom@516: end tom@516: tom@516: % smooth it twice with LPF: tom@516: tom@516: state.lpf1_state = state.lpf1_state + coeffs.lpf_coeff * ... tom@516: (ihc_out - state.lpf1_state); tom@516: tom@516: state.lpf2_state = state.lpf2_state + coeffs.lpf_coeff * ... tom@516: (state.lpf1_state - state.lpf2_state); tom@516: tom@516: ihc_out = state.lpf2_state; tom@516: tom@516: state.ihc_accum = state.ihc_accum + max(0, ihc_out - coeffs.rest_output); tom@516: end