view branches/carfac_cpp/src/CAR.cpp @ 695:2e3672df5698

Simple integration test between CARFAC and SAI. The interface between the two classes is pretty clunky because of the way CARFACOutput stores things. We should work on this, probably by rotating the outer two dimensions of CARFACOutput (i.e. store outputs in containers with sizes n_ears x n_samples x n_channels instead of n_samples x n_ears x n_channels).
author ronw@google.com
date Wed, 26 Jun 2013 23:35:47 +0000
parents d59c0d65624b
children
line wrap: on
line source
#include "CAR.h"
#include "CARFAC_common.h"
#include "CARFAC.h"
#include <cmath>
#include "unit_conversion.h"

CAR_parameters::CAR_parameters():
	  velocity_scale_(0.2),
	  v_offset_(0.01),
	  v2_corner_(0.2),
	  v_damp_max_(0.01),
	  min_zeta_(0.10),
	  first_pole_theta_(0.085*kPi),
	  zero_ratio_(sqrt(2)),
	  high_f_damping_compression_(0.5),
	  erb_per_step_(0.5),
	  min_pole_hz_(30),
	  erb_break_freq_(kDefaultErbBreakFreq),
	  erb_q_(kDefaultErbQ)
{
    // do nothing more!
}

CAR_coefficients::CAR_coefficients(CAR_parameters* car_params_p, float fs,
                                   FloatArray pole_freqs)
{

  float f = pow(car_params_p->zero_ratio_, 2) + 1;

  // TODO: dirty FloatArray initialization.
  r1_coeffs_= pole_freqs;
  a0_coeffs_= pole_freqs;
  c0_coeffs_= pole_freqs;
  h_coeffs_= pole_freqs;
  g0_coeffs_= pole_freqs;
  zr_coeffs_= pole_freqs;

  FloatArray theta = pole_freqs;

  float min_zeta_mod;
  float x;
  float ff = car_params_p->high_f_damping_compression_;

  // TODO: temp loop until we get eigen in  (or we just leave it like this)
  for(float i=0; i<pole_freqs.size(); i++){
      theta[i] *= (2*kPi*fs); // scalar mult.
      c0_coeffs_[i] = sin(theta[i]);
      a0_coeffs_[i] = cos(theta[i]);

      x = theta[i]/kPi;
      zr_coeffs_[i] = kPi * (x - ff * x*x*x);

      min_zeta_mod = (car_params_p->min_zeta_ + 0.25 * (ERB_Hz(
                      pole_freqs[i], car_params_p->erb_break_freq_,
                      car_params_p->erb_q_) / pole_freqs[i]
                     - car_params_p->min_zeta_));

      r1_coeffs_[i] = 1-zr_coeffs_[i]*min_zeta_mod;

      h_coeffs_[i] = c0_coeffs_[i] * f;

      //TODO: g0_coeffs_ calculated here for now. Let's talk about this, need
      // to see the whole picture of what makes sense.
      // Related: I believe CAR, IHC and AGC classes would be beneficial!
      float tmp = 1 - 2*r1_coeffs_[i]*a0_coeffs_[i] + r1_coeffs_[i]*r1_coeffs_[i];
      g0_coeffs_[i] = tmp / ( tmp + h_coeffs_[i]*r1_coeffs_[i]*c0_coeffs_[i]);
  }

}