changeset 622:16918ffbf975

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 d763637a05c5
children d0ff15c36828
files trunk/carfac/agc_params.cc trunk/carfac/agc_params.h trunk/carfac/car_params.cc trunk/carfac/car_params.h trunk/carfac/carfac.cc trunk/carfac/carfac.h trunk/carfac/carfac_common.cc trunk/carfac/carfac_common.h trunk/carfac/carfac_output.cc trunk/carfac/carfac_output.h trunk/carfac/ear.cc trunk/carfac/ear.h trunk/carfac/ear_output.cc trunk/carfac/ear_output.h trunk/carfac/ihc_params.cc trunk/carfac/ihc_params.h trunk/carfac/main.cc
diffstat 17 files changed, 197 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/carfac/agc_params.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/agc_params.cc	Fri May 17 19:52:45 2013 +0000
@@ -27,27 +27,29 @@
 AGCParams::AGCParams() {
   n_stages_ = 4;
   agc_stage_gain_ = 2;
-  FPType agc1f = 1.0;
-  FPType agc2f = 1.65;
+  FPType agc2_factor = 1.65;
+  std::vector<FPType> stage_values = {1.0, 1.4, 2.0, 2.8};
   time_constants_.resize(n_stages_);
-  time_constants_ << 1 * 0.002, 4 * 0.002, 16 * 0.002, 64 * 0.002;
+  agc1_scales_.resize(n_stages_);
+  agc2_scales_.resize(n_stages_);
+  for (int i = 0; i < n_stages_; ++i) {
+    time_constants_(i) = pow(4, i) * 0.002;
+    agc1_scales_(i) = stage_values.at(i);
+    agc2_scales_(i) = stage_values.at(i) * agc2_factor;
+  }
   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;
 }
 
 // The overloaded constructor allows for use of different AGC parameters.
-AGCParams::AGCParams(int ns, FPType agcsg, FPType agcmc, FloatArray tc,
-                     std::vector<int> 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;
+AGCParams::AGCParams(int n_stages, FPType agc_stage_gain, FPType agc_mix_coeff,
+                    FloatArray time_constants, std::vector<int> decimation,
+                    FloatArray agc1_scales, FloatArray agc2_scales) {
+  n_stages_ = n_stages;
+  agc_stage_gain_ = agc_stage_gain;
+  agc_mix_coeff_ = agc_mix_coeff;
+  time_constants_ = time_constants;
+  decimation_ = decimation;
+  agc1_scales_ = agc1_scales;
+  agc2_scales_ = agc2_scales;
 }
\ No newline at end of file
--- a/trunk/carfac/agc_params.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/agc_params.h	Fri May 17 19:52:45 2013 +0000
@@ -27,8 +27,9 @@
 
 struct AGCParams {
   AGCParams();
-  AGCParams(int ns, FPType agcsg, FPType agcmc, FloatArray tc,
-            std::vector<int> dec, FloatArray agc1sc, FloatArray agc2sc);
+  AGCParams(int n_stages, FPType agc_stage_gain, FPType agc_mix_coeff,
+            FloatArray time_constants, std::vector<int> decimation,
+            FloatArray agc1_scales, FloatArray agc2_scales);
   int n_stages_;
   FPType agc_stage_gain_;
   FPType agc_mix_coeff_;
--- a/trunk/carfac/car_params.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/car_params.cc	Fri May 17 19:52:45 2013 +0000
@@ -36,18 +36,20 @@
   erb_q_ = 1000/(24.7*4.37);
 };
 
-CARParams::CARParams(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;
+CARParams::CARParams(FPType velocity_scale, FPType v_offset, FPType min_zeta,
+                     FPType max_zeta, FPType first_pole_theta,
+                     FPType zero_ratio, FPType high_f_damping_compression,
+                     FPType erb_per_step, FPType min_pole_hz_,
+                     FPType erb_break_freq, FPType erb_q_) {
+  velocity_scale_ = velocity_scale;
+  v_offset_ = v_offset;
+  min_zeta_ = min_zeta;
+  max_zeta_ = max_zeta;
+  first_pole_theta_ = first_pole_theta;
+  zero_ratio_ = zero_ratio;
+  high_f_damping_compression_ = high_f_damping_compression;
+  erb_per_step_ = erb_per_step;
+  min_pole_hz_ = min_pole_hz_;
+  erb_break_freq_ = erb_break_freq;
+  erb_q_ = erb_q_;
 };
\ No newline at end of file
--- a/trunk/carfac/car_params.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/car_params.h	Fri May 17 19:52:45 2013 +0000
@@ -27,9 +27,11 @@
 
 struct CARParams {
   CARParams();  // The constructor initializes using default parameter values.
-  CARParams(FPType vs, FPType voff, FPType min_z, FPType max_z, FPType fpt,
-                 FPType zr, FPType hfdc, FPType erbps, FPType mph, FPType erbbf,
-                 FPType erbq);  // This is a method to set non-default params.
+  // This is a method to set non-default params.
+  CARParams(FPType velocity_scale, FPType v_offset, FPType min_zeta,
+            FPType max_zeta, FPType first_pole_theta, FPType zero_ratio,
+            FPType high_f_damping_compression, FPType erb_per_step,
+            FPType min_pole_hz_, FPType erb_break_freq, FPType erb_q_);
   FPType velocity_scale_; // This is used for the velocity nonlinearity.
   FPType v_offset_;  // The offset gives us quadratic part.
   FPType min_zeta_;  // This is the minimum damping factor in mid-freq channels.
--- a/trunk/carfac/carfac.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac.cc	Fri May 17 19:52:45 2013 +0000
@@ -21,11 +21,11 @@
 // limitations under the License.
 
 #include "carfac.h"
-void CARFAC::Design(int n_ears, long fs, CARParams car_params,
+void CARFAC::Design(int n_ears, int32_t fs, CARParams car_params,
                     IHCParams ihc_params, AGCParams agc_params) {
   n_ears_ = n_ears;
   fs_ = fs;
-  ears_ = new Ear[n_ears_];
+  ears_.resize(n_ears_);
   
   n_ch_ = 0;
   FPType pole_hz = car_params.first_pole_theta_ * fs / (2 * PI);
@@ -45,26 +45,28 @@
   // Once we have the basic information about the pole frequencies and the
   // number of channels, we initialize the ear(s).
   for (int i = 0; i < n_ears_; i++) {
-    ears_[i].InitEar(n_ch_, fs_, pole_freqs, car_params, ihc_params, agc_params);
+    ears_.at(i).InitEar(n_ch_, fs_, pole_freqs, car_params, ihc_params,
+                     agc_params);
   }
 }
 
-CARFACOutput CARFAC::Run(FloatArray2d sound_data, bool open_loop) {
+CARFACOutput CARFAC::Run(FloatArray2d sound_data, bool open_loop,
+                         bool store_bm, bool store_ohc, bool store_agc) {
   // We initialize one output object to store the final output.
   CARFACOutput *output = new CARFACOutput();
   // A second object is used to store the output for the individual segments.
   CARFACOutput *seg_output = new CARFACOutput();
   int n_audio_channels = int(sound_data.cols());
-  long seg_len = 441;  // We use a fixed segment length for now.
-  long n_timepoints = sound_data.rows();
-  long n_segs = ceil((n_timepoints * 1.0) / seg_len);
+  int32_t seg_len = 441;  // We use a fixed segment length for now.
+  int32_t n_timepoints = sound_data.rows();
+  int32_t n_segs = ceil((n_timepoints * 1.0) / seg_len);
   output->InitOutput(n_audio_channels, n_ch_, n_timepoints);
   seg_output->InitOutput(n_audio_channels, n_ch_, seg_len);
   // These values store the start and endpoints for each segment
-  long start;
-  long length = seg_len;
+  int32_t start;
+  int32_t length = seg_len;
   // This section loops over the individual audio segments.
-  for (long i = 0; i < n_segs; i++) {
+  for (int32_t i = 0; i < n_segs; i++) {
     // For each segment we calculate the start point and the segment length.
     start = i * seg_len;
     if (i == n_segs - 1) {
@@ -74,7 +76,8 @@
     // Once we've determined the start point and segment length, we run the
     // CARFAC model on the current segment.
     RunSegment(sound_data.block(start, 0, length, n_audio_channels),
-               seg_output, open_loop);
+               seg_output, open_loop, store_bm, store_ohc,
+               store_agc);
     // Afterwards we merge the output for the current segment into the larger
     // output structure for the entire audio file.
     output->MergeOutput(*seg_output, start, length);
@@ -83,10 +86,11 @@
 }
 
 void CARFAC::RunSegment(FloatArray2d sound_data, CARFACOutput *seg_output,
-                        bool open_loop) {
+                        bool open_loop, bool store_bm, bool store_ohc,
+                        bool store_agc) {
   // The number of timepoints is determined from the length of the audio
   // segment.
-  long n_timepoints = sound_data.rows();
+  int32_t n_timepoints = sound_data.rows();
   // The number of ears is equal to the number of audio channels. This could
   // potentially be removed since we already know the n_ears_ during the design
   // stage. 
@@ -94,26 +98,30 @@
   // A nested loop structure is used to iterate through the individual samples
   // for each ear (audio channel).
   bool updated;  // This variable is used by the AGC stage.
-  for (long i = 0; i < n_timepoints; i++) {
+  FloatArray car_out(n_ch_);
+  FloatArray ihc_out(n_ch_);
+  for (int32_t i = 0; i < n_timepoints; i++) {
     for (int j = 0; j < n_ears; j++) {
       // This stores the audio sample currently being processed.
       FPType input = sound_data(i, j);
       // Now we apply the three stages of the model in sequence to the current
       // audio sample.
-      FloatArray car_out = ears_[j].CARStep(input);
-      FloatArray ihc_out = ears_[j].IHCStep(car_out);
-      updated = ears_[j].AGCStep(ihc_out);
+      car_out = ears_.at(j).CARStep(input);
+      ihc_out = ears_.at(j).IHCStep(car_out);
+      updated = ears_.at(j).AGCStep(ihc_out);
       // These lines assign the output of the model for the current sample
       // to the appropriate data members of the current ear in the output
       // object.
-      seg_output->ears_[j].nap_.block(0, i, n_ch_, 1) = ihc_out;
+      seg_output->StoreNAPOutput(i, j, n_ch_, ihc_out);
       // TODO alexbrandmeyer: Check with Dick to determine the C++ strategy for
-      // storing optional output structures.
-      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].ReturnZAMemory();
-      seg_output->ears_[j].agc_.block(0, i, n_ch_, 1) =
-        ears_[j].ReturnZBMemory();
+      // storing optional output structures. Note for revision 271: added flags
+      // to the 'Run' and 'RunSegment' methods to allow selective storage of
+      // the different model output stages.
+      if (store_bm) { seg_output->StoreBMOutput(i, j, n_ch_, car_out); }
+      if (store_ohc) {
+        seg_output->StoreOHCOutput(i, j, n_ch_, ears_.at(j).ReturnZAMemory()); }
+      if (store_agc) {
+        seg_output->StoreAGCOutput(i, j, n_ch_, ears_.at(j).ReturnZBMemory()); }
     }
     if (updated && n_ears > 1) { CrossCouple(); }
     if (! open_loop) { CloseAGCLoop(); }
@@ -130,13 +138,13 @@
         FloatArray stage_state;
         FloatArray this_stage_values = FloatArray::Zero(n_ch_);
         for (int ear = 0; ear < n_ears_; ear++) {
-          stage_state = ears_[ear].ReturnAGCStateMemory(stage);
+          stage_state = ears_.at(ear).ReturnAGCStateMemory(stage);
           this_stage_values += stage_state;
         }
         this_stage_values /= n_ears_;
         for (int ear = 0; ear < n_ears_; ear++) {
-          stage_state = ears_[ear].ReturnAGCStateMemory(stage);
-          ears_[ear].SetAGCStateMemory(stage,
+          stage_state = ears_.at(ear).ReturnAGCStateMemory(stage);
+          ears_.at(ear).SetAGCStateMemory(stage,
                                          stage_state + mix_coeff *
                                          (this_stage_values - stage_state));
         }
@@ -149,11 +157,12 @@
   for (int ear = 0; ear < n_ears_; ear++) {
     FloatArray undamping = 1 - ears_[ear].ReturnAGCStateMemory(1);
     // This updates the target stage gain for the new damping.
-    ears_[ear].SetCARStateDZBMemory(ears_[ear].ReturnZRCoeffs() * undamping -
-                                    ears_[ear].ReturnZBMemory() /
-                                    ears_[ear].ReturnAGCDecimation(1));
-    ears_[ear].SetCARStateDGMemory((ears_[ear].StageGValue(undamping) -
-                                   ears_[ear].ReturnGMemory()) /
-                                   ears_[ear].ReturnAGCDecimation(1));
+    ears_.at(ear).SetCARStateDZBMemory(ears_.at(ear).ReturnZRCoeffs() *
+                                       undamping -
+                                       ears_.at(ear).ReturnZBMemory() /
+                                       ears_.at(ear).ReturnAGCDecimation(1));
+    ears_.at(ear).SetCARStateDGMemory((ears_.at(ear).StageGValue(undamping) -
+                                       ears_.at(ear).ReturnGMemory()) /
+                                       ears_.at(ear).ReturnAGCDecimation(1));
   }
 }
--- a/trunk/carfac/carfac.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac.h	Fri May 17 19:52:45 2013 +0000
@@ -50,25 +50,27 @@
   // 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,
+  void Design(int n_ears, int32_t 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, bool open_loop);
+  CARFACOutput Run(FloatArray2d sound_data, bool open_loop, bool store_bm,
+                   bool store_ohc, bool store_agc);
   // The 'RunSegment' method processes individual sound segments
   void RunSegment(FloatArray2d sound_data, CARFACOutput *seg_output,
-                  bool open_loop);
+                  bool open_loop, bool store_bm, bool store_ohc,
+                  bool store_agc);
   
  private:
   void CrossCouple();
   void CloseAGCLoop();
   
   int n_ears_;  // This is the number of ears.
-  long fs_;  // This is our current sample rate.
+  int32_t fs_;  // This is our current sample rate.
   int n_ch_;  // This is the number of channels in the CARFAC model.
   FPType max_channels_per_octave_;
   // We store an array of Ear objects for mono/stereo/multichannel processing:
-  Ear *ears_; 
+  std::vector<Ear> ears_;
 };
 
 #endif
\ No newline at end of file
--- a/trunk/carfac/carfac_common.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac_common.cc	Fri May 17 19:52:45 2013 +0000
@@ -22,8 +22,6 @@
 
 #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;
--- a/trunk/carfac/carfac_common.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac_common.h	Fri May 17 19:52:45 2013 +0000
@@ -49,8 +49,6 @@
 
 // This section is where the base include operations for the CARFAC project
 // occur.
-// <iostream> is used for debugging output, but it could go in final version.
-#include <iostream>
 // <math.h> is used during coefficient calculations and runtime operations.
 #include <math.h>
 // <vector> is used in place of 2d Eigen Arrays for the AGC memory
@@ -73,8 +71,8 @@
 typedef Eigen::Array<FPType, Dynamic, 1> FloatArray;  // This is a 1d array.
 typedef Eigen::Array<FPType, Dynamic, Dynamic> FloatArray2d;  // This is 2d.
 
-// Two psychoacoustics helper functions are defined here for use by the
-// different processing stages in calculating coeffecients.
+// Two helper functions are defined here for use by the different model stages
+// in calculating coeffecients and during model runtime.
 
 // Function: ERBHz
 // Auditory filter nominal Equivalent Rectangular Bandwidth
@@ -82,7 +80,8 @@
 FPType ERBHz(FPType cf_hz, FPType erb_break_freq, FPType erb_q);
 
 // Function CARFACDetect
-// TODO explain a bit more
+// This returns the IHC detection nonilnearity function of the filter output
+// values.  This is here because it is called both in design and run phases.
 FloatArray CARFACDetect (FloatArray x);
 
 #endif
\ No newline at end of file
--- a/trunk/carfac/carfac_output.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac_output.cc	Fri May 17 19:52:45 2013 +0000
@@ -22,16 +22,36 @@
 
 #include "carfac_output.h"
 
-void CARFACOutput::InitOutput(int n_ears, int n_ch, long n_tp) {
+void CARFACOutput::InitOutput(int n_ears, int n_ch, int32_t n_tp) {
   n_ears_ = n_ears;
-  ears_ = new EarOutput[n_ears_];
+  ears_.resize(n_ears_);
   for (int i = 0; i < n_ears_; i++) {
-    ears_[i].InitOutput(n_ch, n_tp);
+    ears_.at(i).InitOutput(n_ch, n_tp);
   }
 }
 
-void CARFACOutput::MergeOutput(CARFACOutput output, long start, long length) {
+void CARFACOutput::MergeOutput(CARFACOutput output, int32_t start, int32_t length) {
   for (int i = 0; i < n_ears_; i++){
-    ears_[i].MergeOutput(output.ears_[i], start, length);
+    ears_.at(i).MergeOutput(output.ears_[i], start, length);
   }
+}
+
+void CARFACOutput::StoreNAPOutput(int32_t timepoint, int ear, int n_ch,
+                               FloatArray nap) {
+  ears_.at(ear).StoreNAPOutput(timepoint, n_ch, nap);
+}
+
+void CARFACOutput::StoreBMOutput(int32_t timepoint, int ear, int n_ch,
+                                  FloatArray nap) {
+  ears_.at(ear).StoreBMOutput(timepoint, n_ch, nap);
+}
+
+void CARFACOutput::StoreOHCOutput(int32_t timepoint, int ear, int n_ch,
+                                  FloatArray nap) {
+  ears_.at(ear).StoreOHCOutput(timepoint, n_ch, nap);
+}
+
+void CARFACOutput::StoreAGCOutput(int32_t timepoint, int ear, int n_ch,
+                                  FloatArray nap) {
+  ears_.at(ear).StoreNAPOutput(timepoint, n_ch, nap);
 }
\ No newline at end of file
--- a/trunk/carfac/carfac_output.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/carfac_output.h	Fri May 17 19:52:45 2013 +0000
@@ -43,11 +43,17 @@
 
 #include "ear_output.h"
 
-struct CARFACOutput {
-  void InitOutput(int n_ears, int n_ch, long n_tp);
-  void MergeOutput(CARFACOutput output, long start, long length);
+class CARFACOutput {
+ public:
+  void InitOutput(int n_ears, int n_ch, int32_t n_tp);
+  void MergeOutput(CARFACOutput output, int32_t start, int32_t length);
+  void StoreNAPOutput(int32_t timepoint, int ear, int n_ch, FloatArray nap);
+  void StoreBMOutput(int32_t timepoint, int ear, int n_ch, FloatArray bm);
+  void StoreOHCOutput(int32_t timepoint, int ear, int n_ch, FloatArray ohc);
+  void StoreAGCOutput(int32_t timepoint, int ear, int n_ch, FloatArray agc);
+ private:
   int n_ears_;
-  EarOutput *ears_;
+  std::vector<EarOutput> ears_;
 };
 
 #endif
\ No newline at end of file
--- a/trunk/carfac/ear.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ear.cc	Fri May 17 19:52:45 2013 +0000
@@ -25,7 +25,7 @@
 // The 'InitEar' function takes a set of model parameters and initializes the
 // design coefficients and model state variables needed for running the model
 // on a single audio channel. 
-void Ear::InitEar(int n_ch, long fs, FloatArray pole_freqs,
+void Ear::InitEar(int n_ch, int32_t fs, FloatArray pole_freqs,
                   CARParams car_p, IHCParams ihc_p, AGCParams agc_p) {
   // The first section of code determines the number of channels that will be
   // used in the model on the basis of the sample rate and the CAR parameters
@@ -43,7 +43,7 @@
   InitAGCState();
 }
 
-void Ear::DesignFilters(CARParams car_params, long fs,
+void Ear::DesignFilters(CARParams car_params, int32_t fs,
                               FloatArray pole_freqs) {
   car_coeffs_.velocity_scale_ = car_params.velocity_scale_;
   car_coeffs_.v_offset_ = car_params.v_offset_;
@@ -82,7 +82,7 @@
 }
 
 
-void Ear::DesignAGC(AGCParams agc_params, long fs) {
+void Ear::DesignAGC(AGCParams agc_params, int32_t fs) {
   // These data members could probably be initialized locally within the design
   // function.
   agc_coeffs_.n_agc_stages_ = agc_params.n_stages_;
@@ -100,7 +100,7 @@
   FPType mix_coeff = agc_params.agc_mix_coeff_;
   int decim = 1;
   agc_coeffs_.decimation_ = agc_params.decimation_;
-  FPType total_dc_gain = 0;
+  FPType total_dc_gain = 0.0;
   // Here we loop through each of the stages of the AGC.
   for (int stage=0; stage < agc_coeffs_.n_agc_stages_; stage++) {
     FPType tau = time_constants(stage);
@@ -151,13 +151,17 @@
         case 3:
           a = (var + pow(mn, 2) - mn) / 2;
           b = (var + pow(mn, 2) + mn) / 2;
-          fir << a, 1 - a - b, b;
+          fir(0) = a;
+          fir(1) = 1 - a - b;
+          fir(2) = b;
           fir_ok = (fir(2) >= 0.2) ? true : 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;
+          fir(0) = a / 2;
+          fir(1) = 1 - a - b;
+          fir(2) = b / 2;
           fir_ok = (fir(2) >= 0.1) ? true : false;
           break;
         default:
@@ -181,17 +185,17 @@
   agc_coeffs_.detect_scale_ = 1 / total_dc_gain;
 }
 
-void Ear::DesignIHC(IHCParams ihc_params, long fs) {
+void Ear::DesignIHC(IHCParams ihc_params, int32_t fs) {
   if (ihc_params.just_hwr_) {
     ihc_coeffs_.just_hwr_ = ihc_params.just_hwr_;
   } else {
     // This section calculates conductance values using two pre-defined scalars.
     FloatArray x(1);
     FPType conduct_at_10, conduct_at_0;
-    x << 10;
+    x(0) = 10.0;
     x = CARFACDetect(x);
     conduct_at_10 = x(0);
-    x << 0;
+    x(0) = 0.0;
     x = CARFACDetect(x);
     conduct_at_0 = x(0);
     if (ihc_params.one_cap_) {
@@ -349,7 +353,7 @@
   if (ihc_coeffs_.just_hwr_) {
     for (int ch = 0; ch < n_ch_; ch++) {
       FPType a;
-      a = (ac_diff(ch) > 0) ? ac_diff(ch) : 0;
+      a = (ac_diff(ch) > 0.0) ? ac_diff(ch) : 0.0;
       ihc_out(ch) = (a < 2) ? a : 2;
     }
   } else {
@@ -469,8 +473,8 @@
                       (fir_coeffs(2) * (ss_tap2 + ss_tap4));
         break;
       default:
+        break;
         // TODO alexbrandmeyer: determine proper error handling implementation.
-        std::cout << "Error: bad n-taps in AGCSpatialSmooth" << std::endl;
     }
   } else {
     stage_state = AGCSmoothDoubleExponential(stage_state,
@@ -482,9 +486,9 @@
 
 FloatArray Ear::AGCSmoothDoubleExponential(FloatArray stage_state,
                                            FPType pole_z1, FPType pole_z2) {
-  int n_pts = stage_state.size();
+  int32_t n_pts = stage_state.size();
   FPType input;
-  FPType state = 0;
+  FPType state = 0.0;
   // TODO alexbrandmeyer: I'm assuming one dimensional input for now, but this
   // should be verified with Dick for the final version
   for (int i = n_pts - 11; i < n_pts; i ++){
--- a/trunk/carfac/ear.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ear.h	Fri May 17 19:52:45 2013 +0000
@@ -31,7 +31,7 @@
  public:
   // This is the primary initialization function that is called for each
   // Ear object in the CARFAC 'Design' method.
-  void InitEar(int n_ch, long fs, FloatArray pole_freqs, CARParams car_p,
+  void InitEar(int n_ch, int32_t fs, FloatArray pole_freqs, CARParams car_p,
                IHCParams ihc_p, AGCParams agc_p);
   // These three methods apply the different stages of the model in sequence
   // to individual audio samples.
@@ -62,9 +62,9 @@
  private:
   // These methods carry out the design of the coefficient sets for each of the
   // three model stages.
-  void DesignFilters(CARParams car_params, long fs, FloatArray pole_freqs);
-  void DesignIHC(IHCParams ihc_params, long fs);
-  void DesignAGC(AGCParams agc_params, long fs);
+  void DesignFilters(CARParams car_params, int32_t fs, FloatArray pole_freqs);
+  void DesignIHC(IHCParams ihc_params, int32_t fs);
+  void DesignAGC(AGCParams agc_params, int32_t fs);
   // These are the corresponding methods that initialize the model state
   // variables before runtime using the model coefficients.
   void InitIHCState();
--- a/trunk/carfac/ear_output.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ear_output.cc	Fri May 17 19:52:45 2013 +0000
@@ -22,7 +22,7 @@
 
 #include "ear_output.h"
 
-void EarOutput::InitOutput(int n_ch, long n_tp) {
+void EarOutput::InitOutput(int n_ch, int32_t n_tp) {
   n_ch_ = n_ch;
   n_timepoints_ = n_tp;
   nap_.resize(n_ch_, n_timepoints_);
@@ -31,7 +31,7 @@
   agc_.resize(n_ch_, n_timepoints_);
 }
 
-void EarOutput::MergeOutput(EarOutput ear_output, long start, long length) {
+void EarOutput::MergeOutput(EarOutput ear_output, int32_t start, int32_t 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_,
@@ -40,4 +40,20 @@
                                                               length);
   agc_.block(0, start, n_ch_, length) = ear_output.agc_.block(0, 0, n_ch_,
                                                               length);
+}
+
+void EarOutput::StoreNAPOutput(int32_t timepoint, int n_ch, FloatArray nap) {
+  nap_.block(0, timepoint, n_ch_, 1) = nap;
+}
+
+void EarOutput::StoreBMOutput(int32_t timepoint, int n_ch, FloatArray bm) {
+  bm_.block(0, timepoint, n_ch_, 1) = bm;
+}
+
+void EarOutput::StoreOHCOutput(int32_t timepoint, int n_ch, FloatArray ohc) {
+  ohc_.block(0, timepoint, n_ch_, 1) = ohc;
+}
+
+void EarOutput::StoreAGCOutput(int32_t timepoint, int n_ch, FloatArray agc) {
+  agc_.block(0, timepoint, n_ch_, 1) = agc;
 }
\ No newline at end of file
--- a/trunk/carfac/ear_output.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ear_output.h	Fri May 17 19:52:45 2013 +0000
@@ -25,11 +25,17 @@
 
 #include "carfac_common.h"
 
-struct EarOutput {
-  void InitOutput(int n_ch, long n_tp);
-  void MergeOutput(EarOutput output, long start, long length);
+class EarOutput {
+ public:
+  void InitOutput(int n_ch, int32_t n_tp);
+  void MergeOutput(EarOutput output, int32_t start, int32_t length);
+  void StoreNAPOutput(int32_t timepoint, int n_ch, FloatArray nap);
+  void StoreBMOutput(int32_t timepoint, int n_ch, FloatArray bm);
+  void StoreOHCOutput(int32_t timepoint, int n_ch, FloatArray ohc);
+  void StoreAGCOutput(int32_t timepoint, int n_ch, FloatArray agc);
+ private:
   int n_ch_;
-  long n_timepoints_;
+  int32_t n_timepoints_;
   FloatArray2d nap_;
   FloatArray2d nap_decim_;
   FloatArray2d ohc_;
--- a/trunk/carfac/ihc_params.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ihc_params.cc	Fri May 17 19:52:45 2013 +0000
@@ -37,15 +37,15 @@
 
 // The overloaded constructor allows for use of different inner hair cell
 // parameters.
-IHCParams::IHCParams(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;  
+IHCParams::IHCParams(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) {
+  just_hwr_ = just_hwr;
+  one_cap_ = one_cap;
+  tau_lpf_ = tau_lpf;
+  tau1_out_ = tau1_out;
+  tau1_in_ = tau1_in;
+  tau2_out_ = tau2_out;
+  tau2_in_ = tau2_in;
+  ac_corner_hz_ = ac_corner_hz;  
 }
\ No newline at end of file
--- a/trunk/carfac/ihc_params.h	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/ihc_params.h	Fri May 17 19:52:45 2013 +0000
@@ -27,8 +27,9 @@
 
 struct IHCParams {
   IHCParams();
-  IHCParams(bool jh, bool oc, FPType tlpf, FPType t1out, FPType t1in,
-                 FPType t2out, FPType t2in, FPType acchz);
+  IHCParams(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);
   bool just_hwr_;
   bool one_cap_;
   FPType tau_lpf_;
--- a/trunk/carfac/main.cc	Thu May 16 17:33:23 2013 +0000
+++ b/trunk/carfac/main.cc	Fri May 17 19:52:45 2013 +0000
@@ -35,7 +35,6 @@
 // design stage) and sound data (for running the model).
 #include <sndfile.h>
 #include "carfac.h"
-#include <fstream>
 //GoogleTest is now included for running unit tests
 #include <gtest/gtest.h>
 
@@ -51,15 +50,14 @@
   SF_INFO info;
   // Several scalars are used to store relevant information needed for
   // transfering data from the WAV file to an Eigen Array. 
-  long num, num_items;
+  int32_t num, num_items;
   double *buf;
-  long f, sr, c;
+  int32_t f, sr, c;
   // This opens the sound file and prints an error message if the file can't
   // be found.
   sf = sf_open(filename,SFM_READ,&info);
   if (sf == NULL)
   {
-    std::cout << "Failed to open the file" << std::endl;
     return mysnd;
   }
   // Here we store relevant header information in our scalars and use them to
@@ -95,7 +93,6 @@
   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;
@@ -126,10 +123,8 @@
   delete ihc_params;
   delete agc_params;
   // Now we run the model on the test data (using a closed loop for now).
-  CARFACOutput output = mycf->Run(mysnd, false);
+  CARFACOutput output = mycf->Run(mysnd, false, true, true, true);
   // Finally we clear the CARFAC object when we're done.
   delete mycf;
-  //return RUN_ALL_TESTS();;
   return 0;
 }
-