changeset 609:aefe2ca0674f

First version of a C++ implementation by Alex Brandmeyer
author alexbrandmeyer
date Mon, 13 May 2013 22:51:15 +0000
parents fc353426eaad
children 01986636257a
files carfac/agc_coeffs.cc carfac/agc_coeffs.h carfac/agc_params.cc carfac/agc_params.h carfac/agc_state.cc carfac/agc_state.h carfac/car_coeffs.cc carfac/car_coeffs.h carfac/car_params.cc carfac/car_params.h carfac/car_state.cc carfac/car_state.h carfac/carfac.cc carfac/carfac.h carfac/carfac_common.cc carfac/carfac_common.h carfac/carfac_output.cc carfac/carfac_output.h carfac/ear.cc carfac/ear.h carfac/ear_output.cc carfac/ear_output.h carfac/ihc_coeffs.cc carfac/ihc_coeffs.h carfac/ihc_params.cc carfac/ihc_params.h carfac/ihc_state.cc carfac/ihc_state.h carfac/main.cc carfac/test_signal.wav
diffstat 30 files changed, 1980 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_coeffs.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,167 @@
+//
+//  agc_coeffs.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "agc_coeffs.h"
+
+//This method has been created for debugging purposes and depends on <iostream>.
+//Could possibly be removed in the final version to reduce dependencies.
+void AGCCoeffs::OutputCoeffs(){
+  std::cout << "AGCCoeffs Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "n_ch_ = " << n_ch_ << std::endl;
+  std::cout << "n_agc_stages_ = " << n_agc_stages_ << std::endl;
+  std::cout << "agc_stage_gain_ = " << agc_stage_gain_ << std::endl;
+  std::cout << "agc_epsilon_ = " << agc_epsilon_ << std::endl;
+  std::cout << "decimation_ = " << decimation_ << std::endl;
+  std::cout << "agc_pole_z1_ = " << agc_pole_z1_ << std::endl;
+  std::cout << "agc_pole_z2_ = " << agc_pole_z2_ << std::endl;
+  std::cout << "agc_spatial_iterations_ = " << agc_spatial_iterations_
+            << std::endl;
+  std::cout << "agc_spatial_fir_ = " << agc_spatial_fir_ << std::endl;
+  std::cout << "agc_spatial_n_taps_ = " << agc_spatial_n_taps_ << std::endl;
+  std::cout << "agc_mix_coeffs_ = " << agc_mix_coeffs_ << std::endl;
+  std::cout << "agc1_scales_ = " << agc1_scales_ << std::endl;
+  std::cout << "agc2_scales_ = " << agc2_scales_ << std::endl;
+  std::cout << "time_constants_ = " << time_constants_
+            << std::endl << std::endl;
+}
+
+void AGCCoeffs::DesignAGC(AGCParams agc_params, long fs, int n_ch){
+  n_ch_ = n_ch;
+  n_agc_stages_ = agc_params.n_stages_;
+  agc_stage_gain_ = agc_params.agc_stage_gain_;
+  agc1_scales_ = agc_params.agc1_scales_;
+  agc2_scales_ = agc_params.agc2_scales_;
+  time_constants_ = agc_params.time_constants_;
+  agc_epsilon_.resize(n_agc_stages_);
+  agc_pole_z1_.resize(n_agc_stages_);
+  agc_pole_z2_.resize(n_agc_stages_);
+  agc_spatial_iterations_.resize(n_agc_stages_);
+  agc_spatial_n_taps_.resize(n_agc_stages_);
+  agc_spatial_fir_.resize(3,n_agc_stages_);
+  agc_mix_coeffs_.resize(n_agc_stages_);
+  mix_coeff_ = agc_params.agc_mix_coeff_;
+  fir_.resize(3);
+  decim_ = 1;
+  decimation_ = agc_params.decimation_;
+  total_dc_gain_ = 0;
+  
+  for (int stage=0; stage < n_agc_stages_; stage++){
+    tau_ = time_constants_(stage);
+    decim_ = decim_ * decimation_(stage);
+    agc_epsilon_(stage) = 1 - exp((-1 * decim_) / (tau_ * fs));
+    n_times_ = tau_ * (fs / decim_);
+    delay_ = (agc2_scales_(stage) - agc1_scales_(stage)) / n_times_;
+    spread_sq_ = (pow(agc1_scales_(stage),2) + pow(agc2_scales_(stage),2)) /
+    n_times_;
+    u_ = 1 + (1 / spread_sq_);
+    p_ = u_ - sqrt(pow(u_,2) - 1);
+    dp_ = delay_ * (1 - (2 * p_) + pow(p_,2)) / 2;
+    pole_z1_ = p_ - dp_;
+    pole_z2_ = p_ + dp_;
+    agc_pole_z1_(stage) = pole_z1_;
+    agc_pole_z2_(stage) = pole_z2_;
+    n_taps_ = 0;
+    fir_ok_ = 0;
+    n_iterations_ = 1;
+    //initialize FIR coeffs settings
+    try {
+      while (! fir_ok_){
+        switch (n_taps_){
+          case 0:
+            n_taps_ = 3;
+            break;
+          case 3:
+            n_taps_ = 5;
+            break;
+          case 5:
+            n_iterations_ ++;
+            if (n_iterations_ > 16){
+              throw 10; //too many iterations
+            }
+            break;
+          default:
+            throw 20; //bad n_taps
+        }
+        //Design FIR Coeffs
+        FPType var = spread_sq_ / n_iterations_;
+        FPType mn = delay_ / n_iterations_;
+        switch (n_taps_){
+          case 3:
+            a = (var + pow(mn,2) - mn) / 2;
+            b = (var + pow(mn,2) + mn) / 2;
+            fir_ << a, 1 - a - b, b;
+            if (fir_(2) >= 0.2) {
+              fir_ok_ = true;
+            } else {
+              fir_ok_ = false;
+            }
+            break;
+          case 5:
+            a = (((var + pow(mn,2)) * 2/5) - (mn * 2/3)) / 2;
+            b = (((var + pow(mn,2)) * 2/5) + (mn * 2/3)) / 2;
+            fir_ << a/2, 1 - a - b, b/2;
+            if (fir_(2) >= 0.1) {
+              fir_ok_ = true;
+            } else {
+              fir_ok_ = false;
+            }
+            break;
+          default:
+            throw 30; //bad n_taps in FIR design
+        }
+      }
+    }
+    catch (int e) {
+      switch (e) {
+        case 10:
+          std::cout << "ERROR: Too many n_iterations in agc_coeffs.DesignAGC"
+          << std::endl;
+          break;
+        case 20:
+          std::cout << "ERROR: Bad n_taps in agc_coeffs.DesignAGC" << std::endl;
+          break;
+        case 30:
+          std::cout << "ERROR: Bad n_taps in agc_coeffs.DesignAGC/FIR"
+          << std::endl;
+          break;
+        default:
+          std::cout << "ERROR: unknown error in agc_coeffs.DesignAGC"
+          << std::endl;
+      }
+    }
+    //assign output of filter design
+    agc_spatial_iterations_(stage) = n_iterations_;
+    agc_spatial_n_taps_(stage) = n_taps_;
+    agc_spatial_fir_(0,stage) = fir_(0);
+    agc_spatial_fir_(1,stage) = fir_(1);
+    agc_spatial_fir_(2,stage) = fir_(2);
+    total_dc_gain_ = total_dc_gain_ + pow(agc_stage_gain_,(stage));
+    if (stage == 0) {
+      agc_mix_coeffs_(stage) = 0;
+    } else {
+      agc_mix_coeffs_(stage) = mix_coeff_ / (tau_ * (fs /decim_));
+    }
+  }
+  agc_gain_ = total_dc_gain_;
+  detect_scale_ = 1 / total_dc_gain_;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_coeffs.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,71 @@
+//
+//  agc_coeffs.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_AGCCoeffs_h
+#define CARFAC_Open_Source_C__Library_AGCCoeffs_h
+
+#include "agc_params.h"
+
+class AGCCoeffs {
+public:
+  int n_ch_;
+  int n_agc_stages_;
+  int agc_stage_gain_;
+  FloatArray agc_epsilon_; //FloatArray
+  FloatArray decimation_; //FloatArray
+  FloatArray agc_pole_z1_; //FloatArray
+  FloatArray agc_pole_z2_; //FloatArray
+  FloatArray agc_spatial_iterations_; //FloatArray
+  FloatArray2d agc_spatial_fir_; //2-d FloatArray
+  FloatArray agc_spatial_n_taps_; //FloatArray
+  FloatArray agc_mix_coeffs_; //FloatArray
+  FPType agc_gain_;
+  FPType detect_scale_;
+  
+  FloatArray agc1_scales_;
+  FloatArray agc2_scales_;
+  FloatArray time_constants_;
+  FPType tau_;
+  FPType decim_;
+  FPType n_times_;
+  FPType delay_;
+  FPType spread_sq_;
+  FPType u_;
+  FPType p_;
+  FPType dp_;
+  FPType pole_z1_;
+  FPType pole_z2_;
+  int n_taps_;
+  bool fir_ok_;
+  int n_iterations_;
+  FPType total_dc_gain_;
+  FPType a, b;
+  FPType mix_coeff_;
+  FloatArray fir_;
+
+  
+  void OutputCoeffs(); //Method to view coeffs, could go in final version
+  void DesignAGC(AGCParams agc_params, long fs, int n_ch);
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_params.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,62 @@
+//
+//  agc_params.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "agc_params.h"
+
+AGCParams::AGCParams(){
+  n_stages_ = 4;
+  agc_stage_gain_ = 2;
+  FPType agc1f = 1.0;
+  FPType agc2f = 1.65;
+  time_constants_.resize(n_stages_);
+  time_constants_ << 1*0.002, 4*0.002, 16*0.002, 64*0.002;
+  decimation_.resize(n_stages_);
+  decimation_ << 8, 2, 2, 2;
+  agc1_scales_.resize(n_stages_);
+  agc1_scales_ << 1.0 * agc1f, 1.4 * agc1f, 2.0 * agc1f, 2.8 * agc1f;
+  agc2_scales_.resize(n_stages_);
+  agc2_scales_ << 1.0 * agc2f, 1.4 * agc2f, 2.0 * agc2f, 2.8 * agc2f;
+  agc_mix_coeff_ = 0.5;
+}
+
+void AGCParams::SetParams(int ns, FPType agcsg, FPType agcmc, FloatArray tc,
+                          FloatArray dec, FloatArray agc1sc, FloatArray agc2sc){
+  n_stages_ = ns;
+  agc_stage_gain_ = agcsg;
+  agc_mix_coeff_ = agcmc;
+  time_constants_ = tc;
+  decimation_ = dec;
+  agc1_scales_ = agc1sc;
+  agc2_scales_ = agc2sc;
+}
+
+void AGCParams::OutputParams(){
+  std::cout << "AGCParams Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "n_stages_ = " << n_stages_ << std::endl;
+  std::cout << "agc_stage_gain_ = " << agc_stage_gain_ << std::endl;
+  std::cout << "agc_mix_coeff_ = " << agc_mix_coeff_ << std::endl;
+  std::cout << "time_constants_ = " << time_constants_ << std::endl;
+  std::cout << "decimation_ = " << decimation_ << std::endl;
+  std::cout << "agc1_scales_ = " << agc1_scales_ << std::endl;
+  std::cout << "agc2_scales_ = " << agc2_scales_ << std::endl << std::endl;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_params.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,45 @@
+//
+//  agc_params.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_AGCParams_h
+#define CARFAC_Open_Source_C__Library_AGCParams_h
+
+#include "carfac_common.h"
+
+class AGCParams {
+public:
+  int n_stages_;
+  FPType agc_stage_gain_;
+  FPType agc_mix_coeff_;
+  FloatArray time_constants_;
+  FloatArray decimation_;
+  FloatArray agc1_scales_;
+  FloatArray agc2_scales_;
+  
+  
+  void OutputParams();
+  void SetParams(int ns, FPType agcsg,FPType agcmc, FloatArray tc,
+                 FloatArray dec, FloatArray agc1sc, FloatArray agc2sc);
+  AGCParams();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_state.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,31 @@
+//
+//  agc_state.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "agc_state.h"
+
+void AGCState::InitAGCState(AGCCoeffs agc_coeffs){
+  n_ch_ = agc_coeffs.n_ch_;
+  n_agc_stages_ = agc_coeffs.n_agc_stages_;
+  agc_memory_ = FloatArray2d::Zero(n_ch_, n_agc_stages_);
+  input_accum_ = FloatArray2d::Zero(n_ch_, n_agc_stages_);
+  decim_phase_ = FloatArray::Zero(n_agc_stages_);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/agc_state.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,38 @@
+//
+//  agc_state.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_AGCState_h
+#define CARFAC_Open_Source_C__Library_AGCState_h
+
+#include "agc_coeffs.h"
+
+class AGCState {
+public:
+  int n_ch_;
+  int n_agc_stages_;
+  FloatArray2d agc_memory_;
+  FloatArray2d input_accum_;
+  FloatArray decim_phase_;
+  void InitAGCState(AGCCoeffs agc_coeffs);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_coeffs.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,77 @@
+//
+//  car_coeffs.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "car_coeffs.h"
+
+//This method has been created for debugging purposes and depends on <iostream>.
+//Could possibly be removed in the final version to reduce dependencies. 
+void CARCoeffs::OutputCoeffs(){
+  std::cout << "CARCoeffs Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "n_ch_ = " << n_ch_ << std::endl;
+  std::cout << "velocity_scale_ = " << velocity_scale_ << std::endl;
+  std::cout << "v_offset_ = " << v_offset_ << std::endl;
+  std::cout << "r1_coeffs_ = " << r1_coeffs_ << std::endl;
+  std::cout << "a0_coeffs_ = " << a0_coeffs_ << std::endl;
+  std::cout << "c0_coeffs_ = " << c0_coeffs_ << std::endl;
+  std::cout << "h_coeffs_ = " << h_coeffs_ << std::endl;
+  std::cout << "g0_coeffs_ = " << g0_coeffs_ << std::endl;
+  std::cout << "zr_coeffs_ = " << zr_coeffs_ << std::endl << std::endl;
+}
+
+void CARCoeffs::DesignFilters(CARParams car_params, long fs,
+                              FloatArray pole_freqs[]){
+  
+  n_ch_ = int(pole_freqs->size());
+  velocity_scale_ = car_params.velocity_scale_;
+  v_offset_ = car_params.v_offset_;
+  FloatArray p_freqs = *pole_freqs;
+  r1_coeffs_.resize(n_ch_);
+  a0_coeffs_.resize(n_ch_);
+  c0_coeffs_.resize(n_ch_);
+  h_coeffs_.resize(n_ch_);
+  g0_coeffs_.resize(n_ch_);
+  FPType f = car_params.zero_ratio_ * car_params.zero_ratio_ - 1;
+  FloatArray theta = p_freqs * ((2 * PI) / fs);
+  c0_coeffs_ = sin(theta);
+  a0_coeffs_ = cos(theta);
+  FPType ff = car_params.high_f_damping_compression_;
+  FloatArray x = theta / PI;
+  zr_coeffs_ = PI * (x - (ff * (x * x * x)));//change to exponet
+  FPType max_zeta = car_params.max_zeta_;
+  FPType min_zeta = car_params.min_zeta_;
+  r1_coeffs_ = (1 - (zr_coeffs_ * max_zeta));
+  FPType curfreq;
+  FloatArray erb_freqs(n_ch_);
+  for (int ch=0; ch < n_ch_; ch++){
+    curfreq = p_freqs(ch);
+    erb_freqs(ch) = ERBHz(curfreq, car_params.erb_break_freq_,
+                           car_params.erb_q_);
+  }
+  FloatArray min_zetas = min_zeta + (0.25 * ((erb_freqs / p_freqs) - min_zeta));
+  zr_coeffs_ = zr_coeffs_ * (max_zeta - min_zetas);
+  h_coeffs_ = c0_coeffs_ * f;
+  FloatArray relative_undamping = FloatArray::Ones(n_ch_);
+  FloatArray r = r1_coeffs_ + (zr_coeffs_ * relative_undamping);
+  g0_coeffs_ = (1 - (2 * r * a0_coeffs_) + (r * r)) /
+            (1 - (2 * r * a0_coeffs_) + (h_coeffs_ * r * c0_coeffs_) + (r * r));
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_coeffs.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,46 @@
+//
+//  car_coeffs.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_CARCoeffs_h
+#define CARFAC_Open_Source_C__Library_CARCoeffs_h
+
+#include "car_params.h"
+
+class CARCoeffs {
+public:
+  int n_ch_;
+  FPType velocity_scale_;
+  FPType v_offset_;
+  FloatArray r1_coeffs_;
+  FloatArray a0_coeffs_;
+  FloatArray c0_coeffs_;
+  FloatArray h_coeffs_;
+  FloatArray g0_coeffs_;
+  FloatArray zr_coeffs_;
+  
+  void OutputCoeffs(); //Method to view coeffs, could go in final version
+  void DesignFilters(CARParams car_params, long fs,
+                     FloatArray pole_freqs[]);
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_params.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,72 @@
+//
+//  car_params.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "car_params.h"
+
+CARParams::CARParams(){
+  velocity_scale_ = 0.1; //for the velocity nonlinearity
+  v_offset_ = 0.04; //offset gives quadratic part
+  min_zeta_ = 0.1; //minimum damping factor in mid-freq channels
+  max_zeta_ = 0.35; //maximum damping factor in mid-freq channels
+  first_pole_theta_ = 0.85 * PI;
+  zero_ratio_ = 1.4142; //how far zero is above pole
+  high_f_damping_compression_ = 0.5; //0 to 1 to compress theta
+  erb_per_step_ = 0.5; //assume G&M's ERB formula
+  min_pole_hz_ = 30;
+  erb_break_freq_ = 165.3; //Greenwood map's break frequency
+  erb_q_ = 1000/(24.7*4.37);
+};
+
+//This method has been created for debugging purposes and depends on <iostream>.
+//Could possibly be removed in the final version to reduce dependencies.
+void CARParams::OutputParams(){
+  std::cout << "CARParams Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "velocity_scale_ = " << velocity_scale_ << std::endl;
+  std::cout << "v_offset_ = " << v_offset_ << std::endl;
+  std::cout << "min_zeta_ = " << min_zeta_ << std::endl;
+  std::cout << "max_zeta_ = " << max_zeta_ << std::endl;
+  std::cout << "first_pole_theta_ = " << first_pole_theta_ << std::endl;
+  std::cout << "zero_ratio_ = " << zero_ratio_ << std::endl;
+  std::cout << "high_f_damping_compression_ = " << high_f_damping_compression_
+            << std::endl;
+  std::cout << "erb_per_step_ = " << erb_per_step_ << std::endl;
+  std::cout << "min_pole_hz_ = " << min_pole_hz_ << std::endl;
+  std::cout << "erb_break_freq_ = " << erb_break_freq_ << std::endl;
+  std::cout << "erb_q_ = " << erb_q_ << std::endl << std::endl;
+}
+
+void CARParams::SetParams(FPType vs, FPType voff, FPType min_z, FPType max_z,
+                          FPType fpt, FPType zr, FPType hfdc, FPType erbps,
+                          FPType mph, FPType erbbf, FPType erbq) {  
+  velocity_scale_ = vs;
+  v_offset_ = voff;
+  min_zeta_ = min_z;
+  max_zeta_ = max_z;
+  first_pole_theta_ = fpt;
+  zero_ratio_ = zr;
+  high_f_damping_compression_ = hfdc;
+  erb_per_step_ = erbps;
+  min_pole_hz_ = mph;
+  erb_break_freq_ = erbbf;
+  erb_q_ = erbq;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_params.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,50 @@
+//
+//  car_params.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_CARParams_h
+#define CARFAC_Open_Source_C__Library_CARParams_h
+
+#include "carfac_common.h"
+
+class CARParams {
+public:
+  FPType velocity_scale_; //for the velocity nonlinearity
+  FPType v_offset_; //offset gives quadratic part
+  FPType min_zeta_; //minimum damping factor in mid-freq channels
+  FPType max_zeta_; //maximum damping factor in mid-freq channels
+  FPType first_pole_theta_;
+  FPType zero_ratio_; //how far zero is above pole
+  FPType high_f_damping_compression_; //0 to 1 to compress theta
+  FPType erb_per_step_; //assume G&M's ERB formula
+  FPType min_pole_hz_;
+  FPType erb_break_freq_; //Greenwood map's break frequency
+  FPType erb_q_; //G&M's high-cf ratio
+  
+  CARParams(); //Constructor initializes default parameter values
+  void OutputParams(); //Output current parameter values using std::cout
+  void SetParams(FPType vs, FPType voff, FPType min_z, FPType max_z, FPType fpt,
+                 FPType zr, FPType hfdc, FPType erbps, FPType mph, FPType erbbf,
+                 FPType erbq); //Method to set non-default params
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_state.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,37 @@
+//
+//  car_state.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "car_state.h"
+
+void CARState::InitCARState(CARCoeffs car_coeffs){
+  n_ch_ = car_coeffs.n_ch_;
+  z1_memory_ = FloatArray::Zero(n_ch_);
+  z2_memory_ = FloatArray::Zero(n_ch_);
+  za_memory_ = FloatArray::Zero(n_ch_);
+  zb_memory_ = car_coeffs.zr_coeffs_;
+  dzb_memory_ = FloatArray::Zero(n_ch_);
+  zy_memory_ = FloatArray::Zero(n_ch_);
+  g_memory_ = car_coeffs.g0_coeffs_;
+  dg_memory_ = FloatArray::Zero(n_ch_);
+  
+  
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/car_state.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,45 @@
+//
+//  car_state.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_CARState_h
+#define CARFAC_Open_Source_C__Library_CARState_h
+
+#include "car_coeffs.h"
+
+class CARState {
+public:
+  int n_ch_;
+  FloatArray z1_memory_;
+  FloatArray z2_memory_;
+  FloatArray za_memory_;
+  FloatArray zb_memory_;
+  FloatArray dzb_memory_;
+  FloatArray zy_memory_;
+  FloatArray g_memory_;
+  FloatArray dg_memory_;
+  
+  void InitCARState(CARCoeffs car_coeffs);
+  
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,82 @@
+//
+//  carfac.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "carfac.h"
+void CARFAC::Design(int n_ears, long fs, CARParams car_params,
+                    IHCParams ihc_params, AGCParams agc_params){
+  n_ears_ = n_ears;
+  fs_ = fs;
+  ears_ = new Ear[n_ears_];
+  for (int i = 0; i < n_ears_; i++){
+    ears_[i].InitEar(fs_, car_params,ihc_params,agc_params);
+  }
+  n_ch_ = ears_[0].car_coeffs_.n_ch_;
+}
+
+CARFACOutput CARFAC::Run(FloatArray2d sound_data){
+  //to store the final output
+  CARFACOutput *output = new CARFACOutput();
+  //to store the output of the individual segments
+  CARFACOutput *seg_output = new CARFACOutput();
+  
+  int n_audio_channels = int(sound_data.cols());
+  long seg_len = 441; //Fixed segment length for now
+  long n_timepoints = sound_data.rows();
+  double n_segs = ceil(double(n_timepoints)/double(seg_len));
+  output->InitOutput(n_audio_channels, n_ch_, n_timepoints);
+  seg_output->InitOutput(n_audio_channels, n_ch_, seg_len);
+  //loop over individual audio segments
+  long start, length; //to store the start and endpoints for each segment
+  for (long i = 0; i < long(n_segs); i++){
+    //determine start and end points
+    start = (i * seg_len);
+    if (i < n_segs - 1){
+      length = seg_len;
+    } else {
+      length = n_timepoints - start; //the last segment can be shorter than the rest
+    }
+    RunSegment(sound_data.block(start,0,length,n_audio_channels),seg_output);
+    output->MergeOutput(*seg_output, start, length);
+  }
+  
+  return *output;
+}
+
+void CARFAC::RunSegment(FloatArray2d sound_data, CARFACOutput *seg_output){
+  long n_timepoints = sound_data.rows();
+  int n_ears = int(sound_data.cols());
+  for (long i = 0; i < n_timepoints; i++){
+    for (int j = 0; j < n_ears; j++){
+      FPType input = sound_data(i,j);
+      FloatArray car_out = ears_[j].CARStep(input);
+      FloatArray ihc_out = ears_[j].IHCStep(car_out);
+      bool updated = ears_[j].AGCStep(ihc_out);
+      seg_output->ears_[j].nap_.block(0,i,n_ch_,1) = ihc_out;
+      seg_output->ears_[j].bm_.block(0,i,n_ch_,1) = car_out;
+      seg_output->ears_[j].ohc_.block(0,1,n_ch_,1) =
+        ears_[j].car_state_.za_memory_;
+      seg_output->ears_[j].agc_.block(0,i,n_ch_,1) =
+        ears_[j].car_state_.zb_memory_;
+    }
+  }
+  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,71 @@
+//
+//  carfac.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+//
+// *****************************************************************************
+// Class: CARFAC
+// *****************************************************************************
+// The CARFAC class is the top-level class implementing the CAR-FAC C++ model.
+// A CARFAC object knows how to design its details from a modest set of
+// parameters, and knows how to process sound signals to produce "neural
+// activity patterns" (NAPs) which are contained in a CARFACOutput object.
+//
+// The 'Design' method is used to intialize the CARFAC model, and is passed
+// a set of CAR, IHC and AGC parameters along with sound file information
+// (channels and sample rate).
+//
+// The two methods 'Run' and 'RunSegment' are responsible for
+// processing sound signals. These both take two dimensional Eigen float arrays
+// (samples x channels) as arguments and return CARFACOutput objects.
+
+#ifndef CARFAC_Open_Source_C__Library_CARFAC_h
+#define CARFAC_Open_Source_C__Library_CARFAC_h
+
+#include "ear.h"
+#include "carfac_output.h"
+
+class CARFAC {
+public:
+  int n_ears_; //number of ears
+  long fs_; //sample rate
+  int n_ch_; //number of channels in the CARFAC model
+  Ear *ears_; //array of Ear objects for mono/stereo/multichannel processing
+  
+  // The 'Design' method takes a set of CAR, IHC and AGC parameters along with
+  // arguments specifying the number of 'ears' (audio file channels) and sample
+  // rate. This initializes a vector of 'Ear' objects -- one for mono, two for
+  // stereo, or more.  Each 'Ear' includes various sub-objects representing the
+  // parameters, designs (coeffs) ,and states of different parts of the CAR-FAC
+  // model.
+  void Design(int n_ears, long fs, CARParams car_params, IHCParams ihc_params,
+              AGCParams agc_params);
+  
+  //The 'Run' method processes an entire file with the current model, using
+  //subsequent calls to the 'RunSegment' method
+  CARFACOutput Run(FloatArray2d sound_data);
+  
+  //The 'RunSegment' method processes individual sound segments
+  void RunSegment(FloatArray2d sound_data, CARFACOutput *seg_output);
+};
+
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac_common.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,60 @@
+//
+//  carfac_common.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "carfac_common.h"
+
+//Auditory filter nominal Equivalent Rectangular Bandwidth
+//Ref: Glasberg and Moore: Hearing Research, 47 (1990), 103-138
+FPType ERBHz (FPType cf_hz, FPType erb_break_freq, FPType erb_q) {
+  
+  FPType erb;
+  erb = (erb_break_freq + cf_hz) / erb_q;
+  return erb;
+}
+
+//An IHC-like sigmoidal detection nonlinearity for the CARFAC.
+//Resulting conductance is in about [0...1.3405]
+FPType CARFACDetect (FPType x) {
+  
+  FPType conductance, z;
+  FPType a = 0.175;
+  //offset of low-end tail into neg x territory
+  //this parameter is adjusted for the book, to make the 20% DC response
+  //threshold at 0.1
+  z  = x + a;
+  conductance = pow(z,3) / (pow(z,3) + pow(z,2) + 0.1);
+  //zero is the final answer for many points:
+  return conductance;
+}
+
+FloatArray CARFACDetect (FloatArray x) {
+  
+  FloatArray conductance, z;
+  FPType a = 0.175;
+  //offset of low-end tail into neg x territory
+  //this parameter is adjusted for the book, to make the 20% DC response
+  //threshold at 0.1
+  z  = x + a;
+  conductance = (z * z * z) / ((z * z * z) + (z * z) + 0.1);
+  //zero is the final answer for many points:
+  return conductance;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac_common.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,71 @@
+//
+//  carfac_common.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+//
+// *****************************************************************************
+// carfac_common.h
+// *****************************************************************************
+// This file contains the base level definitions and includes used within the
+// CARFAC C++ library. It also defines some low level functions which are used
+// during the calculation of the various coefficient sets required by the model.
+//
+// The current implementation of the library is dependent on the use of the
+// Eigen C++ library for linear algebra. Specifically, Eigen Arrays are used
+// extensively for coefficient wise operations during both the design and run
+// stages of the model.
+//
+// The 'FPType' typedef is specified in this file in order to enable quick
+// switching between precision levels (i.e. float vs. double) throughout the
+// library. The remainder of the code uses this type for specifying floating
+// point scalars.
+//
+// Two additional typedefs are defined for one and two dimensional arrays:
+// FloatArray and FloatArray2d. These in turn make use of FPType so that the
+// precision level across floating point data is consistent.
+//
+// The functions 'ERBHz' and 'CARFACDetect' are defined here, and are used
+// during the design stage of a CARFAC model. 
+
+#ifndef CARFAC_Open_Source_C__Library_CARFACCommon_h
+#define CARFAC_Open_Source_C__Library_CARFACCommon_h
+
+#include <iostream> //Used for debugging output, could go in final version
+#include <math.h> //Used during coefficient calculations
+#include <Eigen/Dense> //Used for 1d and 2d floating point arrays
+using namespace Eigen;
+
+#define PI 3.141592
+typedef float FPType; //Used to enable easy switching in precision level
+
+//typedefs for Eigen floating point arrays
+typedef Eigen::Array<FPType,Dynamic,1> FloatArray; //1d floating point array
+typedef Eigen::Array<FPType,Dynamic,Dynamic> FloatArray2d; //2d fpoint array
+
+// Function: ERBHz
+// Auditory filter nominal Equivalent Rectangular Bandwidth
+// Ref: Glasberg and Moore: Hearing Research, 47 (1990), 103-138
+FPType ERBHz(FPType cf_hz, FPType erb_break_freq, FPType erb_q);
+
+// Function CARFACDetect
+// TODO explain a bit more
+FPType CARFACDetect (FPType x);
+FloatArray CARFACDetect (FloatArray x);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac_output.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,37 @@
+//
+//  carfac_output.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "carfac_output.h"
+
+void CARFACOutput::InitOutput(int n_ears, int n_ch, long n_tp){
+  n_ears_ = n_ears;
+  ears_ = new EarOutput[n_ears_];
+  for (int i = 0; i < n_ears_; i++){
+    ears_[i].InitOutput(n_ch,n_tp);
+  }
+}
+
+void CARFACOutput::MergeOutput(CARFACOutput output, long start, long length){
+  for (int i = 0; i < n_ears_; i++){
+    ears_[i].MergeOutput(output.ears_[i], start, length);
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/carfac_output.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,54 @@
+//
+//  carfac_output.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+//
+// *****************************************************************************
+// Class: CARFACOutput
+// *****************************************************************************
+// The CARFACOutput object stores an array of EarOuput objects. It is meant as a
+// container for the output generated by the CARFAC object's 'Run' and
+// 'RunSegment' methods. Depending on the number of audio channels in the  input
+// data, the CARFACOutput will have 1 or more EarOutput obects, each of which
+// contains a set of two dimensional float arrays (FloatArray2d) representing
+// the neural activation patterns (NAPs) generated by the CARFAC model.
+//
+// The 'InitOutput' method is used to initialize the arrays in each of the
+// EarOutput sub-objects once the target data dimensions ears (n_ears), channels
+// (n_ch) and timepoints (n_tp) are known.
+//
+// The 'MergeOutput' method is for integrating a smaller CARFACOutput into a
+// larger CARFACOutput object. This is intended to be used in the context of
+// the CARFAC class's 'Run' and 'RunSegments' methods. 
+
+#ifndef CARFAC_Open_Source_C__Library_carfac_output_h
+#define CARFAC_Open_Source_C__Library_carfac_output_h
+
+#include "ear_output.h"
+
+class CARFACOutput {
+public:
+  int n_ears_;
+  EarOutput *ears_;
+  void InitOutput(int n_ears, int n_ch, long n_tp);
+  void MergeOutput(CARFACOutput output, long start, long length);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ear.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,268 @@
+//
+//  ear.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "ear.h"
+
+void Ear::InitEar(long fs, CARParams car_p, IHCParams ihc_p, AGCParams agc_p){
+  car_params_ = car_p;
+  ihc_params_ = ihc_p;
+  agc_params_ = agc_p;
+  n_ch_ = 0;
+  FPType pole_hz = car_params_.first_pole_theta_ * fs / (2 * PI);
+  while (pole_hz > car_params_.min_pole_hz_) {
+    n_ch_++;
+    pole_hz = pole_hz - car_params_.erb_per_step_ *
+    ERBHz(pole_hz, car_params_.erb_break_freq_, car_params_.erb_q_);
+  }
+  FloatArray pole_freqs(n_ch_);
+  pole_hz = car_params_.first_pole_theta_ * fs / (2 * PI);
+  for(int ch=0;ch < n_ch_; ch++){
+    pole_freqs(ch) = pole_hz;
+    pole_hz = pole_hz - car_params_.erb_per_step_ *
+    ERBHz(pole_hz, car_params_.erb_break_freq_, car_params_.erb_q_);
+  }
+  max_channels_per_octave_ = log(2) / log(pole_freqs(0) / pole_freqs(1));
+  car_coeffs_.DesignFilters(car_params_, fs, &pole_freqs);
+  agc_coeffs_.DesignAGC(agc_params_, fs, n_ch_);
+  ihc_coeffs_.DesignIHC(ihc_params_, fs, n_ch_);
+  car_state_.InitCARState(car_coeffs_);
+  agc_state_.InitAGCState(agc_coeffs_);
+  ihc_state_.InitIHCState(ihc_coeffs_);
+
+}
+
+FloatArray Ear::CARStep(FPType input){
+  FloatArray g(n_ch_);
+  FloatArray zb(n_ch_);
+  FloatArray za(n_ch_);
+  FloatArray v(n_ch_);
+  FloatArray nlf(n_ch_);
+  FloatArray r(n_ch_);
+  FloatArray z1(n_ch_);
+  FloatArray z2(n_ch_);
+  FloatArray zy(n_ch_);
+  FPType in_out;
+  
+  // do the DOHC stuff:
+  g = car_state_.g_memory_ + car_state_.dg_memory_; //interp g
+  zb = car_state_.zb_memory_ + car_state_.dzb_memory_; //AGC interpolation state
+  // update the nonlinear function of "velocity", and zA (delay of z2):
+  za = car_state_.za_memory_;
+  v = car_state_.z2_memory_ - za;
+  nlf = OHC_NLF(v);
+  r = car_coeffs_.r1_coeffs_ + (zb * nlf); // zB * nfl is "undamping" delta r
+  za = car_state_.z2_memory_;
+  // now reduce state by r and rotate with the fixed cos/sin coeffs:
+  z1 = r * ((car_coeffs_.a0_coeffs_ * car_state_.z1_memory_) -
+            (car_coeffs_.c0_coeffs_ * car_state_.z2_memory_));
+  z2 = r * ((car_coeffs_.c0_coeffs_ * car_state_.z1_memory_) +
+            (car_coeffs_.a0_coeffs_ * car_state_.z2_memory_));
+  zy = car_coeffs_.h_coeffs_ * z2;
+  // Ripple input-output path, instead of parallel, to avoid delay...
+  // this is the only part that doesn't get computed "in parallel":
+  in_out = input;
+  for (int ch = 0; ch < n_ch_; ch++){
+    z1(ch) = z1(ch) + in_out;
+    // ripple, saving final channel outputs in zY
+    in_out = g(ch) * (in_out + zy(ch));
+    zy(ch) = in_out;
+  }
+  car_state_.z1_memory_ = z1;
+  car_state_.z2_memory_ = z2;
+  car_state_.za_memory_ = za;
+  car_state_.zb_memory_ = zb;
+  car_state_.zy_memory_ = zy;
+  car_state_.g_memory_ = g;
+  // car_out is equal to zy state;
+  return zy;
+}
+
+// start with a quadratic nonlinear function, and limit it via a
+// rational function; make the result go to zero at high
+// absolute velocities, so it will do nothing there.
+FloatArray Ear::OHC_NLF(FloatArray velocities){
+  FloatArray nlf(n_ch_);
+  nlf = 1 / ((velocities * car_coeffs_.velocity_scale_) +
+             (car_coeffs_.v_offset_ * car_coeffs_.v_offset_));
+  return nlf;
+}
+
+// One sample-time update of inner-hair-cell (IHC) model, including the
+// detection nonlinearity and one or two capacitor state variables.
+FloatArray Ear::IHCStep(FloatArray car_out){
+  FloatArray ihc_out(n_ch_);
+  FloatArray ac_diff(n_ch_);
+  FloatArray conductance(n_ch_);
+  ac_diff = car_out - ihc_state_.ac_coupler_;
+  ihc_state_.ac_coupler_ = ihc_state_.ac_coupler_ +
+                           (ihc_coeffs_.ac_coeff_ * ac_diff);
+  if (ihc_coeffs_.just_hwr_) {
+    //TODO Figure out best implementation with Eigen max/min methods
+    for (int ch = 0; ch < n_ch_; ch++){
+      FPType a;
+      if (ac_diff(ch) > 0){
+        a = ac_diff(ch);
+      } else {
+        a = 0;
+      }
+      if (a < 2){
+        ihc_out(ch) = a;
+      } else {
+        ihc_out(ch) = 2;
+      }
+    }
+    
+  } else {
+    conductance = CARFACDetect(ac_diff);
+    if (ihc_coeffs_.one_cap_) {
+      ihc_out = conductance * ihc_state_.cap1_voltage_;
+      ihc_state_.cap1_voltage_ = ihc_state_.cap1_voltage_ -
+                                 (ihc_out * ihc_coeffs_.out1_rate_) +
+                                 ((1 - ihc_state_.cap1_voltage_)
+                                  * ihc_coeffs_.in1_rate_);
+    } else {
+      ihc_out = conductance * ihc_state_.cap2_voltage_;
+      ihc_state_.cap1_voltage_ = ihc_state_.cap1_voltage_ -
+                      ((ihc_state_.cap1_voltage_ - ihc_state_.cap2_voltage_)
+                      * ihc_coeffs_.out1_rate_) +
+                      ((1 - ihc_state_.cap1_voltage_) * ihc_coeffs_.in1_rate_);
+      ihc_state_.cap2_voltage_ = ihc_state_.cap2_voltage_ -
+                          (ihc_out * ihc_coeffs_.out2_rate_) +
+                          ((ihc_state_.cap1_voltage_ - ihc_state_.cap2_voltage_)
+                          * ihc_coeffs_.in2_rate_);
+    }
+    // smooth it twice with LPF:
+    ihc_out = ihc_out * ihc_coeffs_.output_gain_;
+    ihc_state_.lpf1_state_ = ihc_state_.lpf1_state_ +
+                  (ihc_coeffs_.lpf_coeff_ * (ihc_out - ihc_state_.lpf1_state_));
+    ihc_state_.lpf2_state_ = ihc_state_.lpf2_state_ +
+                  (ihc_coeffs_.lpf_coeff_ *
+                   (ihc_state_.lpf1_state_ - ihc_state_.lpf2_state_));
+    ihc_out = ihc_state_.lpf2_state_ - ihc_coeffs_.rest_output_;
+  }
+  ihc_state_.ihc_accum_ += ihc_out;
+  return ihc_out;
+}
+
+bool Ear::AGCStep(FloatArray ihc_out){
+  int stage = 0;
+  FloatArray agc_in(n_ch_);
+  agc_in = agc_coeffs_.detect_scale_ * ihc_out;
+  bool updated = AGCRecurse(stage, agc_in);
+  return updated;
+}
+
+bool Ear::AGCRecurse(int stage, FloatArray agc_in){
+  bool updated = true;
+  // decim factor for this stage, relative to input or prev. stage:
+  int decim = agc_coeffs_.decimation_(stage);
+  // decim phase of this stage (do work on phase 0 only):
+  //TODO FIX MODULO
+  
+  int decim_phase = agc_state_.decim_phase_(stage);
+  decim_phase = decim_phase % decim;
+  agc_state_.decim_phase_(stage) = decim_phase;
+  // accumulate input for this stage from detect or previous stage:
+  agc_state_.input_accum_.block(0,stage,n_ch_,1) =
+                        agc_state_.input_accum_.block(0,stage,n_ch_,1) + agc_in;
+  
+  // nothing else to do if it's not the right decim_phase
+  if (decim_phase == 0){
+    // do lots of work, at decimated rate.
+    // decimated inputs for this stage, and to be decimated more for next:
+    agc_in = agc_state_.input_accum_.block(0,stage,n_ch_,1) / decim;
+    // reset accumulator:
+    agc_state_.input_accum_.block(0,stage,n_ch_,1) = FloatArray::Zero(n_ch_);
+    
+    if (stage < (agc_coeffs_.decimation_.size() - 1)){
+      // recurse to evaluate next stage(s)
+      updated = AGCRecurse(stage+1, agc_in);
+      // and add its output to this stage input, whether it updated or not:
+      agc_in = agc_in + (agc_coeffs_.agc_stage_gain_ *
+                         agc_state_.agc_memory_.block(0,stage+1,n_ch_,1));
+    }
+    FloatArray agc_stage_state = agc_state_.agc_memory_.block(0,stage,n_ch_,1);
+    // first-order recursive smoothing filter update, in time:
+    agc_stage_state = agc_stage_state + (agc_coeffs_.agc_epsilon_(stage) *
+                                         (agc_in - agc_stage_state));
+    agc_stage_state = AGCSpatialSmooth(stage, agc_stage_state);
+    agc_state_.agc_memory_.block(0,stage,n_ch_,1) = agc_stage_state;
+  } else {
+    updated = false;
+  }
+  return updated;
+}
+
+FloatArray Ear::AGCSpatialSmooth(int stage, FloatArray stage_state){
+  int n_iterations = agc_coeffs_.agc_spatial_iterations_(stage);
+  bool use_fir;
+  if (n_iterations < 4){
+    use_fir = true;
+  } else {
+    use_fir = false;
+  }
+  
+  if (use_fir) {
+    FloatArray fir_coeffs = agc_coeffs_.agc_spatial_fir_.block(0,stage,3,1);
+    FloatArray ss_tap1(n_ch_);
+    FloatArray ss_tap2(n_ch_);
+    FloatArray ss_tap3(n_ch_);
+    FloatArray ss_tap4(n_ch_);
+    int n_taps = agc_coeffs_.agc_spatial_n_taps_(stage);
+    //Initialize first two taps of stage state, used for both cases
+    ss_tap1(0) = stage_state(0);
+    ss_tap1.block(1,0,n_ch_-1,1) = stage_state.block(0,0,n_ch_-1,1);
+    ss_tap2(n_ch_-1) = stage_state(n_ch_-1);
+    ss_tap2.block(0,0,n_ch_-1,1) = stage_state.block(1,0,n_ch_-1,1);
+    switch (n_taps) {
+      case 3:
+        stage_state = (fir_coeffs(0) * ss_tap1) +
+                      (fir_coeffs(1) * stage_state) +
+                      (fir_coeffs(2) * ss_tap2);
+        break;
+      case 5:
+        //Initialize last two taps of stage state, used for 5-tap case
+        ss_tap3(0) = stage_state(0);
+        ss_tap3(1) = stage_state(1);
+        ss_tap3.block(2,0,n_ch_-2,1) = stage_state.block(0,0,n_ch_-2,1);
+        ss_tap4(n_ch_-2) = stage_state(n_ch_-1);
+        ss_tap4(n_ch_-1) = stage_state(n_ch_-2);
+        ss_tap4.block(0,0,n_ch_-2,1) = stage_state.block(2,0,n_ch_-2,1);
+        
+        stage_state = (fir_coeffs(0) * (ss_tap3 + ss_tap1)) +
+                      (fir_coeffs(1) * stage_state) +
+                      (fir_coeffs(2) * (ss_tap2 + ss_tap4));
+        break;
+      default:
+        //TODO Throw Error
+        std::cout << "Error: bad n-taps in AGCSpatialSmooth" << std::endl;
+    }
+    
+  } else {
+    stage_state = AGCSmoothDoubleExponential(stage_state);
+  }
+  return stage_state;
+}
+
+FloatArray Ear::AGCSmoothDoubleExponential(FloatArray stage_state){
+  return stage_state;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ear.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,55 @@
+//
+//  ear.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_Ear_h
+#define CARFAC_Open_Source_C__Library_Ear_h
+
+#include "car_state.h"
+#include "ihc_state.h"
+#include "agc_state.h"
+
+
+class Ear {
+public:
+  int n_ch_;
+  FPType max_channels_per_octave_;
+  CARParams car_params_;
+  IHCParams ihc_params_;
+  AGCParams agc_params_;
+  CARCoeffs car_coeffs_;
+  IHCCoeffs ihc_coeffs_;
+  AGCCoeffs agc_coeffs_;
+  CARState car_state_;
+  IHCState ihc_state_;
+  AGCState agc_state_;
+  
+  void InitEar(long fs, CARParams car_p, IHCParams ihc_p, AGCParams agc_p);
+  FloatArray CARStep(FPType input);
+  FloatArray OHC_NLF(FloatArray velocities);
+  FloatArray IHCStep(FloatArray car_out);
+  bool AGCStep(FloatArray ihc_out);
+  bool AGCRecurse(int stage, FloatArray agc_in);
+  FloatArray AGCSpatialSmooth(int stage, FloatArray stage_state);
+  FloatArray AGCSmoothDoubleExponential(FloatArray stage_state);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ear_output.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,43 @@
+//
+//  ear_output.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "ear_output.h"
+
+void EarOutput::InitOutput(int n_ch, long n_tp){
+  n_ch_ = n_ch;
+  n_timepoints_ = n_tp;
+  nap_.resize(n_ch_,n_timepoints_);
+  bm_.resize(n_ch_,n_timepoints_);
+  ohc_.resize(n_ch_,n_timepoints_);
+  agc_.resize(n_ch_,n_timepoints_);
+}
+
+void EarOutput::MergeOutput(EarOutput ear_output, long start, long length){
+  nap_.block(0, start, n_ch_, length) = ear_output.nap_.block(0, 0, n_ch_,
+                                                              length);
+  bm_.block(0, start, n_ch_, length) = ear_output.bm_.block(0, 0, n_ch_,
+                                                            length);
+  ohc_.block(0, start, n_ch_, length) = ear_output.ohc_.block(0, 0, n_ch_,
+                                                              length);
+  agc_.block(0, start, n_ch_, length) = ear_output.agc_.block(0, 0, n_ch_,
+                                                              length);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ear_output.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,41 @@
+//
+//  ear_output.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C___Library_ear_output_h
+#define CARFAC_Open_Source_C___Library_ear_output_h
+
+#include "carfac_common.h"
+
+class EarOutput {
+public:
+  int n_ch_;
+  long n_timepoints_;
+  FloatArray2d nap_;
+  FloatArray2d nap_decim_;
+  FloatArray2d ohc_;
+  FloatArray2d agc_;
+  FloatArray2d bm_;
+  void InitOutput(int n_ch, long n_tp);
+  void MergeOutput(EarOutput output, long start, long length);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_coeffs.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,97 @@
+//
+//  ihc_coeffs.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "ihc_coeffs.h"
+
+//This method has been created for debugging purposes and depends on <iostream>.
+//Could possibly be removed in the final version to reduce dependencies.
+void IHCCoeffs::OutputCoeffs(){
+  std::cout << "IHCCoeffs Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "n_ch_ = " << n_ch_ << std::endl;
+  std::cout << "just_hwr_ = " << just_hwr_ << std::endl;
+  std::cout << "one_cap_ = " << one_cap_ << std::endl;
+  std::cout << "lpf_coeff_ = " << lpf_coeff_ << std::endl;
+  std::cout << "out1_rate_ = " << out1_rate_ << std::endl;
+  std::cout << "in1_rate_ = " << in1_rate_ << std::endl;
+  std::cout << "out2_rate_ = " << out2_rate_ << std::endl;
+  std::cout << "in2_rate_ = " << in2_rate_ << std::endl;
+  std::cout << "output_gain_ = " << output_gain_ << std::endl;
+  std::cout << "rest_output_ = " << rest_output_ << std::endl;
+  std::cout << "rest_cap1_ = " << rest_cap1_ << std::endl;
+  std::cout << "rest_cap2_ = " << rest_cap2_ << std::endl;
+  std::cout << "ac_coeff_ = " << ac_coeff_ << std::endl << std::endl;
+}
+
+void IHCCoeffs::DesignIHC(IHCParams ihc_params, long fs, int n_ch){
+  if (ihc_params.just_hwr_){
+    n_ch_ = n_ch;
+    just_hwr_ = ihc_params.just_hwr_;
+  } else {
+    if (ihc_params.one_cap_){
+      ro_ = 1 / CARFACDetect(10);
+      c_ = ihc_params.tau1_out_ / ro_;
+      ri_ = ihc_params.tau1_in_ / c_;
+      saturation_output_ = 1 / ((2 * ro_) + ri_);
+      r0_ = 1 / CARFACDetect(0);
+      current_ = 1 / (ri_ + r0_);
+      cap1_voltage_ = 1 - (current_ * ri_);
+      
+      n_ch_ = n_ch;
+      just_hwr_ = false;
+      lpf_coeff_ = 1 - exp( -1 / (ihc_params.tau_lpf_ * fs));
+      out1_rate_ = ro_ / (ihc_params.tau1_out_ * fs);
+      in1_rate_ = 1 / (ihc_params.tau1_in_ * fs);
+      one_cap_ = ihc_params.one_cap_;
+      output_gain_ = 1 / (saturation_output_ - current_);
+      rest_output_ = current_ / (saturation_output_ - current_);
+      rest_cap1_ = cap1_voltage_;
+
+      
+    } else {
+      ro_ = 1 / CARFACDetect(10);
+      c2_ = ihc_params.tau2_out_ / ro_;
+      r2_ = ihc_params.tau2_in_ / c2_;
+      c1_ = ihc_params.tau1_out_ / r2_;
+      r1_ = ihc_params.tau1_in_ / c1_;
+      saturation_output_ = 1 / (2 * ro_ + r2_ + r1_);
+      r0_ = 1 / CARFACDetect(0);
+      current_ = 1 / (r1_ + r2_ + r0_);
+      cap1_voltage_ = 1 - (current_ * r1_);
+      cap2_voltage_ = cap1_voltage_ - (current_ * r2_);
+      
+      n_ch_ = n_ch;
+      just_hwr_ = false;
+      lpf_coeff_ = 1 - exp(-1 / (ihc_params.tau_lpf_ * fs));
+      out1_rate_ = 1 / (ihc_params.tau1_out_ * fs);
+      in1_rate_ = 1 / (ihc_params.tau1_in_ * fs);
+      out2_rate_ = ro_ / (ihc_params.tau2_out_ * fs);
+      in2_rate_ = 1 / (ihc_params.tau2_in_ * fs);
+      one_cap_ = ihc_params.one_cap_;
+      output_gain_ = 1 / (saturation_output_ - current_);
+      rest_output_ = current_ / (saturation_output_ - current_);
+      rest_cap1_ = cap1_voltage_;
+      rest_cap2_ = cap2_voltage_;
+    }
+  }
+  ac_coeff_ = 2 * PI * ihc_params.ac_corner_hz_ / fs;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_coeffs.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,52 @@
+//
+//  ihc_coeffs.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_IHCCoeffs_h
+#define CARFAC_Open_Source_C__Library_IHCCoeffs_h
+
+#include "ihc_params.h"
+
+class IHCCoeffs {
+public:
+  int n_ch_;
+  bool just_hwr_;
+  bool one_cap_;
+  FPType lpf_coeff_;
+  FPType out1_rate_;
+  FPType in1_rate_;
+  FPType out2_rate_;
+  FPType in2_rate_;
+  FPType output_gain_;
+  FPType rest_output_;
+  FPType rest_cap1_;
+  FPType rest_cap2_;
+  FPType ac_coeff_;
+  
+  FPType ro_, c_, ri_, r0_, saturation_output_, current_, cap1_voltage_,
+         cap2_voltage_;
+  FPType c2_, r2_, c1_, r1_;
+  
+  void OutputCoeffs(); //Method to view coeffs, could go in final version
+  void DesignIHC(IHCParams ihc_params, long fs, int n_ch);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_params.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,65 @@
+//
+//  ihc_params.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "ihc_params.h"
+
+
+//Default constructor for IHCParams initializes with the settings from Lyon's
+//book 'Human and Machine Hearing'
+IHCParams::IHCParams(){
+  just_hwr_ = false; //not just a simple HWR
+  one_cap_ = true; //uses the Allen model, as in Lyon's book
+  tau_lpf_ = 0.000080; //80 microseconds smoothing twice
+  tau1_out_ = 0.0005; //depletion tau is pretty fast
+  tau1_in_ = 0.010; //recovery tau is slower
+  tau2_out_ = 0.0025;
+  tau2_in_ = 0.005;
+  ac_corner_hz_ = 20;
+}
+
+//OutputParams method uses <iostream> for debugging purposes, could go in the
+//final version
+void IHCParams::OutputParams(){
+  std::cout << "IHCParams Values" << std::endl;
+  std::cout << "****************" << std::endl;
+  std::cout << "just_hwr_ = " << just_hwr_ << std::endl;
+  std::cout << "one_cap_ = " << one_cap_ << std::endl;
+  std::cout << "tau_lpf_ = " << tau_lpf_ << std::endl;
+  std::cout << "tau1_out_ = " << tau1_out_ << std::endl;
+  std::cout << "tau1_in_ = " << tau1_in_ << std::endl;
+  std::cout << "tau2_out_ = " << tau2_out_ << std::endl;
+  std::cout << "tau2_in_ = " << tau2_in_ << std::endl;
+  std::cout << "ac_corner_hz_ = " << ac_corner_hz_ << std::endl << std::endl;
+}
+
+//SetParams method allows for use of different inner hair cell parameters
+void IHCParams::SetParams(bool jh, bool oc, FPType tlpf, FPType t1out,
+                          FPType t1in, FPType t2out, FPType t2in, FPType acchz){
+  just_hwr_ = jh;
+  one_cap_ = oc;
+  tau_lpf_ = tlpf;
+  tau1_out_ = t1out;
+  tau1_in_ = t1in;
+  tau2_out_ = t2out;
+  tau2_in_ = t2in;
+  ac_corner_hz_ = acchz;  
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_params.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,45 @@
+//
+//  ihc_params.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_IHCParams_h
+#define CARFAC_Open_Source_C__Library_IHCParams_h
+
+#include "carfac_common.h"
+
+class IHCParams {
+public:
+  bool just_hwr_;
+  bool one_cap_;
+  FPType tau_lpf_;
+  FPType tau1_out_;
+  FPType tau1_in_;
+  FPType tau2_out_;
+  FPType tau2_in_;
+  FPType ac_corner_hz_;
+  
+  IHCParams();
+  void OutputParams(); //Output current parameter values using std::cout
+  void SetParams(bool jh, bool oc, FPType tlpf, FPType t1out, FPType t1in,
+                 FPType t2out, FPType t2in, FPType acchz);//Method to set non-default params
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_state.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,39 @@
+//
+//  ihc_state.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#include "ihc_state.h"
+
+void IHCState::InitIHCState(IHCCoeffs ihc_coeffs){
+  n_ch_ = ihc_coeffs.n_ch_;
+  ihc_accum_ = FloatArray::Zero(n_ch_);
+  if (! ihc_coeffs.just_hwr_){
+    ac_coupler_ = FloatArray::Zero(n_ch_);
+    lpf1_state_ = ihc_coeffs.rest_output_ * FloatArray::Ones(n_ch_);
+    lpf2_state_ = ihc_coeffs.rest_output_ * FloatArray::Ones(n_ch_);
+    if (ihc_coeffs.one_cap_){
+      cap1_voltage_ = ihc_coeffs.rest_cap1_ * FloatArray::Ones(n_ch_);
+    } else {
+      cap1_voltage_ = ihc_coeffs.rest_cap1_ * FloatArray::Ones(n_ch_);
+      cap2_voltage_ = ihc_coeffs.rest_cap2_ * FloatArray::Ones(n_ch_);
+    }
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/ihc_state.h	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,42 @@
+//
+//  ihc_state.h
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+
+#ifndef CARFAC_Open_Source_C__Library_IHCState_h
+#define CARFAC_Open_Source_C__Library_IHCState_h
+
+#include "ihc_coeffs.h"
+
+class IHCState {
+public:
+  int n_ch_;
+  FloatArray ihc_accum_;
+  FloatArray cap1_voltage_;
+  FloatArray cap2_voltage_;
+  FloatArray lpf1_state_;
+  FloatArray lpf2_state_;
+  FloatArray ac_coupler_;
+  
+  void InitIHCState(IHCCoeffs ihc_coeffs);
+  
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/carfac/main.cc	Mon May 13 22:51:15 2013 +0000
@@ -0,0 +1,117 @@
+//
+//  main.cc
+//  CARFAC Open Source C++ Library
+//
+//  Created by Alex Brandmeyer on 5/10/13.
+//
+// This C++ 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.
+//
+// *****************************************************************************
+// main.cc
+// *****************************************************************************
+// This 'main' file is not currently intended as part of the CARFAC distribution,
+// but serves as a testbed for debugging and implementing various aspects of the
+// library. It currently includes the "libsndfile" API for loading soundfiles:
+//
+//    http://www.mega-nerd.com/libsndfile/
+//
+// I've currently tested the code on Mac OS X 10.8 using XCode and dynamically
+// linking to the libsndfile.dylib file. Two helper functions 'ReadSound' and
+// 'ReadSoundInfo' are used to obtain header information (needed for the CARFAC
+// design stage) and sound data (for running the model).
+#include <sndfile.h>
+#include "carfac.h"
+
+// ReadSound takes a character array (filename string) as an argument and
+// returns a two dimensional (samples x channels) FloatArray (Eigen ArrayXX)
+// containing the sound data
+FloatArray2d ReadSound(const char * filename){
+  FloatArray2d mysnd; //output data
+  SNDFILE *sf; 
+  SF_INFO info;
+  long num, num_items;
+  double *buf;
+  long f,sr,c;
+  sf = sf_open(filename,SFM_READ,&info);
+  if (sf == NULL)
+  {
+    std::cout << "Failed to open the file" << std::endl;
+    return mysnd;
+  }
+  f = info.frames;
+  sr = info.samplerate;
+  c = info.channels;
+  num_items = f*c;
+  buf = new double[num_items];
+  num = sf_read_double(sf,buf,num_items);
+  mysnd.resize(f,c);
+  int j = 0;
+  for(int i = 0; i < num_items; i = i + 2){
+    mysnd(j,0) = buf[i];
+    mysnd(j,1) = buf[i+1];
+    j++;
+  }
+  sf_close(sf);
+  return mysnd;
+};
+
+// ReadSoundInfo takes a character array (filename string) as an argument and
+// returns an SF_INFO structure containing the sample rate and channel info
+// needed during the call to CARFAC::Design
+SF_INFO ReadSoundInfo(const char * filename){
+  SNDFILE *sf;
+  SF_INFO info;
+  sf = sf_open(filename,SFM_READ,&info);
+  if (sf == NULL)
+  {
+    std::cout << "Failed to open the file" << std::endl;
+    return info;
+  }
+  return info;
+};
+
+
+
+
+// This 'main' function serves as the primary testbed for this C++ CARFAC
+// implementation. It currently uses a hardcoded filename to obtain sound file
+// info and sound data, and designs a CARFAC on the basis of the header data
+// using the default parameters.
+int main()
+{
+  //Here we specify a path to a test file
+  const char * filename = "/Users/alexbrandmeyer/aimc/carfac/test_signal.wav";
+  
+  //Now we load the header info and sound data
+  SF_INFO info = ReadSoundInfo(filename);
+  FloatArray2d mysnd = ReadSound(filename);
+  //These initialze the default parameter objects needed for the CARFAC design
+  CARParams *car_params = new CARParams();
+  IHCParams *ihc_params = new IHCParams();
+  AGCParams *agc_params = new AGCParams();
+  
+  //This initializes the CARFAC object and runs the design method
+  CARFAC *mycf = new CARFAC();
+  mycf->Design(info.channels,info.samplerate, *car_params, *ihc_params,
+               *agc_params);
+  std::cout << "CARFAC Object Created" << std::endl;
+  
+  //Now we run the model on the test data
+  CARFACOutput output = mycf->Run(mysnd);
+  return 0;
+}
+
Binary file carfac/test_signal.wav has changed