Mercurial > hg > aimc
diff carfac/ear.cc @ 640:d08c02c8e26f
More small style revisions to C++ CARFAC, adjusted struct member variable naming, header guards and #include structure.
author | alexbrandmeyer |
---|---|
date | Wed, 29 May 2013 15:37:28 +0000 |
parents | efc5b1b54f63 |
children | 8b70f4cf00c7 |
line wrap: on
line diff
--- a/carfac/ear.cc Tue May 28 17:54:18 2013 +0000 +++ b/carfac/ear.cc Wed May 29 15:37:28 2013 +0000 @@ -44,27 +44,27 @@ } void Ear::InitCARState() { - car_state_.z1_memory_.setZero(n_ch_); - car_state_.z2_memory_.setZero(n_ch_); - car_state_.za_memory_.setZero(n_ch_); - car_state_.zb_memory_ = car_coeffs_.zr_coeffs_; - car_state_.dzb_memory_.setZero(n_ch_); - car_state_.zy_memory_.setZero(n_ch_); - car_state_.g_memory_ = car_coeffs_.g0_coeffs_; - car_state_.dg_memory_.setZero(n_ch_); + car_state_.z1_memory.setZero(n_ch_); + car_state_.z2_memory.setZero(n_ch_); + car_state_.za_memory.setZero(n_ch_); + car_state_.zb_memory = car_coeffs_.zr_coeffs; + car_state_.dzb_memory.setZero(n_ch_); + car_state_.zy_memory.setZero(n_ch_); + car_state_.g_memory = car_coeffs_.g0_coeffs; + car_state_.dg_memory.setZero(n_ch_); } void Ear::InitIHCState() { - ihc_state_.ihc_accum_ = FloatArray::Zero(n_ch_); - if (! ihc_coeffs_.just_half_wave_rectify_) { - ihc_state_.ac_coupler_.setZero(n_ch_); - ihc_state_.lpf1_state_.setConstant(n_ch_, ihc_coeffs_.rest_output_); - ihc_state_.lpf2_state_.setConstant(n_ch_, ihc_coeffs_.rest_output_); - if (ihc_coeffs_.one_capacitor_) { - ihc_state_.cap1_voltage_.setConstant(n_ch_, ihc_coeffs_.rest_cap1_); + ihc_state_.ihc_accum = FloatArray::Zero(n_ch_); + if (! ihc_coeffs_.just_half_wave_rectify) { + ihc_state_.ac_coupler.setZero(n_ch_); + ihc_state_.lpf1_state.setConstant(n_ch_, ihc_coeffs_.rest_output); + ihc_state_.lpf2_state.setConstant(n_ch_, ihc_coeffs_.rest_output); + if (ihc_coeffs_.one_capacitor) { + ihc_state_.cap1_voltage.setConstant(n_ch_, ihc_coeffs_.rest_cap1); } else { - ihc_state_.cap1_voltage_.setConstant(n_ch_, ihc_coeffs_.rest_cap1_); - ihc_state_.cap2_voltage_.setConstant(n_ch_, ihc_coeffs_.rest_cap2_); + ihc_state_.cap1_voltage.setConstant(n_ch_, ihc_coeffs_.rest_cap1); + ihc_state_.cap2_voltage.setConstant(n_ch_, ihc_coeffs_.rest_cap2); } } } @@ -73,43 +73,43 @@ int n_agc_stages = agc_coeffs_.size(); agc_state_.resize(n_agc_stages); for (auto& stage_state : agc_state_) { - stage_state.decim_phase_ = 0; - stage_state.agc_memory_.setZero(n_ch_); - stage_state.input_accum_.setZero(n_ch_); + stage_state.decim_phase = 0; + stage_state.agc_memory.setZero(n_ch_); + stage_state.input_accum.setZero(n_ch_); } } void Ear::CARStep(const FPType input) { // This interpolates g. - car_state_.g_memory_ = car_state_.g_memory_ + car_state_.dg_memory_; + car_state_.g_memory = car_state_.g_memory + car_state_.dg_memory; // This calculates the AGC interpolation state. - car_state_.zb_memory_ = car_state_.zb_memory_ + car_state_.dzb_memory_; + car_state_.zb_memory = car_state_.zb_memory + car_state_.dzb_memory; // This updates the nonlinear function of 'velocity' along with zA, which is // a delay of z2. FloatArray nonlinear_fun(n_ch_); - FloatArray velocities = car_state_.z2_memory_ - car_state_.za_memory_; + FloatArray velocities = car_state_.z2_memory - car_state_.za_memory; OHCNonlinearFunction(velocities, &nonlinear_fun); // Here, zb_memory_ * nonlinear_fun is "undamping" delta r. - FloatArray r = car_coeffs_.r1_coeffs_ + (car_state_.zb_memory_ * + FloatArray r = car_coeffs_.r1_coeffs + (car_state_.zb_memory * nonlinear_fun); - car_state_.za_memory_ = car_state_.z2_memory_; + car_state_.za_memory = car_state_.z2_memory; // Here we reduce the CAR state by r and rotate with the fixed cos/sin coeffs. - FloatArray z1 = r * ((car_coeffs_.a0_coeffs_ * car_state_.z1_memory_) - - (car_coeffs_.c0_coeffs_ * car_state_.z2_memory_)); - car_state_.z2_memory_ = r * - ((car_coeffs_.c0_coeffs_ * car_state_.z1_memory_) + - (car_coeffs_.a0_coeffs_ * car_state_.z2_memory_)); - car_state_.zy_memory_ = car_coeffs_.h_coeffs_ * car_state_.z2_memory_; + FloatArray z1 = r * ((car_coeffs_.a0_coeffs * car_state_.z1_memory) - + (car_coeffs_.c0_coeffs * car_state_.z2_memory)); + car_state_.z2_memory = r * + ((car_coeffs_.c0_coeffs * car_state_.z1_memory) + + (car_coeffs_.a0_coeffs * car_state_.z2_memory)); + car_state_.zy_memory = car_coeffs_.h_coeffs * car_state_.z2_memory; // This section ripples the input-output path, to avoid delay... // It's the only part that doesn't get computed "in parallel": FPType in_out = input; for (int ch = 0; ch < n_ch_; ch++) { z1(ch) = z1(ch) + in_out; // This performs the ripple, and saves the final channel outputs in zy. - in_out = car_state_.g_memory_(ch) * (in_out + car_state_.zy_memory_(ch)); - car_state_.zy_memory_(ch) = in_out; + in_out = car_state_.g_memory(ch) * (in_out + car_state_.zy_memory(ch)); + car_state_.zy_memory(ch) = in_out; } - car_state_.z1_memory_ = z1; + car_state_.z1_memory = z1; } // We start with a quadratic nonlinear function, and limit it via a @@ -117,57 +117,57 @@ // absolute velocities, so it will do nothing there. void Ear::OHCNonlinearFunction(const FloatArray& velocities, FloatArray* nonlinear_fun) { - *nonlinear_fun = (1 + ((velocities * car_coeffs_.velocity_scale_) + - car_coeffs_.v_offset_).square()).inverse(); + *nonlinear_fun = (1 + ((velocities * car_coeffs_.velocity_scale) + + car_coeffs_.v_offset).square()).inverse(); } // This step is a one sample-time update of the inner-hair-cell (IHC) model, // including the detection nonlinearity and either one or two capacitor state // variables. void Ear::IHCStep(const FloatArray& car_out) { - FloatArray 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_half_wave_rectify_) { + FloatArray 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_half_wave_rectify) { FloatArray output(n_ch_); for (int ch = 0; ch < n_ch_; ++ch) { FPType a = (ac_diff(ch) > 0.0) ? ac_diff(ch) : 0.0; output(ch) = (a < 2) ? a : 2; } - ihc_state_.ihc_out_ = output; + ihc_state_.ihc_out = output; } else { FloatArray conductance = CARFACDetect(ac_diff); - if (ihc_coeffs_.one_capacitor_) { - ihc_state_.ihc_out_ = conductance * ihc_state_.cap1_voltage_; - ihc_state_.cap1_voltage_ = ihc_state_.cap1_voltage_ - - (ihc_state_.ihc_out_ * ihc_coeffs_.out1_rate_) + - ((1 - ihc_state_.cap1_voltage_) * ihc_coeffs_.in1_rate_); + if (ihc_coeffs_.one_capacitor) { + ihc_state_.ihc_out = conductance * ihc_state_.cap1_voltage; + ihc_state_.cap1_voltage = ihc_state_.cap1_voltage - + (ihc_state_.ihc_out * ihc_coeffs_.out1_rate) + + ((1 - ihc_state_.cap1_voltage) * ihc_coeffs_.in1_rate); } else { - ihc_state_.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_state_.ihc_out_ * ihc_coeffs_.out2_rate_) + - ((ihc_state_.cap1_voltage_ - ihc_state_.cap2_voltage_) - * ihc_coeffs_.in2_rate_); + ihc_state_.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_state_.ihc_out * ihc_coeffs_.out2_rate) + + ((ihc_state_.cap1_voltage - ihc_state_.cap2_voltage) + * ihc_coeffs_.in2_rate); } // Here we smooth the output twice using a LPF. - ihc_state_.ihc_out_ *= ihc_coeffs_.output_gain_; - ihc_state_.lpf1_state_ += ihc_coeffs_.lpf_coeff_ * - (ihc_state_.ihc_out_ - ihc_state_.lpf1_state_); - ihc_state_.lpf2_state_ += ihc_coeffs_.lpf_coeff_ * - (ihc_state_.lpf1_state_ - ihc_state_.lpf2_state_); - ihc_state_.ihc_out_ = ihc_state_.lpf2_state_ - ihc_coeffs_.rest_output_; + ihc_state_.ihc_out *= ihc_coeffs_.output_gain; + ihc_state_.lpf1_state += ihc_coeffs_.lpf_coeff * + (ihc_state_.ihc_out - ihc_state_.lpf1_state); + ihc_state_.lpf2_state += ihc_coeffs_.lpf_coeff * + (ihc_state_.lpf1_state - ihc_state_.lpf2_state); + ihc_state_.ihc_out = ihc_state_.lpf2_state - ihc_coeffs_.rest_output; } - ihc_state_.ihc_accum_ += ihc_state_.ihc_out_; + ihc_state_.ihc_accum += ihc_state_.ihc_out; } bool Ear::AGCStep(const FloatArray& ihc_out) { int stage = 0; - int n_stages = agc_coeffs_[0].n_agc_stages_; - FPType detect_scale = agc_coeffs_[n_stages - 1].detect_scale_; + int n_stages = agc_coeffs_[0].n_agc_stages; + FPType detect_scale = agc_coeffs_[n_stages - 1].detect_scale; bool updated = AGCRecurse(stage, detect_scale * ihc_out); return updated; } @@ -177,33 +177,33 @@ const auto& agc_coeffs = agc_coeffs_[stage]; auto& agc_state = agc_state_[stage]; // This is the decim factor for this stage, relative to input or prev. stage: - int decim = agc_coeffs.decimation_; + int decim = agc_coeffs.decimation; // This is the decim phase of this stage (do work on phase 0 only): - int decim_phase = agc_state.decim_phase_ + 1; + int decim_phase = agc_state.decim_phase + 1; decim_phase = decim_phase % decim; - agc_state.decim_phase_ = decim_phase; + agc_state.decim_phase = decim_phase; // Here we accumulate input for this stage from the previous stage: - agc_state.input_accum_ += agc_in; + agc_state.input_accum += agc_in; // We don't do anything if it's not the right decim_phase. if (decim_phase == 0) { // Now we do lots of work, at the decimated rate. // These are the decimated inputs for this stage, which will be further // decimated at the next stage. - agc_in = agc_state.input_accum_ / decim; + agc_in = agc_state.input_accum / decim; // This resets the accumulator. - agc_state.input_accum_ = FloatArray::Zero(n_ch_); + agc_state.input_accum = FloatArray::Zero(n_ch_); if (stage < (agc_coeffs_.size() - 1)) { // Now we recurse to evaluate the next stage(s). updated = AGCRecurse(stage + 1, agc_in); // Afterwards we add its output to this stage input, whether it updated or // not. - agc_in += agc_coeffs.agc_stage_gain_ * - agc_state_[stage + 1].agc_memory_; + agc_in += agc_coeffs.agc_stage_gain * + agc_state_[stage + 1].agc_memory; } // This performs a first-order recursive smoothing filter update, in time. - agc_state.agc_memory_ += agc_coeffs.agc_epsilon_ * - (agc_in - agc_state.agc_memory_); - AGCSpatialSmooth(agc_coeffs_[stage], &agc_state.agc_memory_); + agc_state.agc_memory += agc_coeffs.agc_epsilon * + (agc_in - agc_state.agc_memory); + AGCSpatialSmooth(agc_coeffs_[stage], &agc_state.agc_memory); updated = true; } else { updated = false; @@ -213,18 +213,18 @@ void Ear::AGCSpatialSmooth(const AGCCoeffs& agc_coeffs, FloatArray* stage_state) { - int n_iterations = agc_coeffs.agc_spatial_iterations_; + int n_iterations = agc_coeffs.agc_spatial_iterations; bool use_fir; use_fir = (n_iterations < 4) ? true : false; if (use_fir) { - FPType fir_coeffs_left = agc_coeffs.agc_spatial_fir_left_; - FPType fir_coeffs_mid = agc_coeffs.agc_spatial_fir_mid_; - FPType fir_coeffs_right = agc_coeffs.agc_spatial_fir_right_; + FPType fir_coeffs_left = agc_coeffs.agc_spatial_fir_left; + FPType fir_coeffs_mid = agc_coeffs.agc_spatial_fir_mid; + FPType fir_coeffs_right = agc_coeffs.agc_spatial_fir_right; 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_; + int n_taps = agc_coeffs.agc_spatial_n_taps; // This initializes the first two taps of stage state, which are used for // both possible cases. ss_tap1(0) = (*stage_state)(0); @@ -256,8 +256,8 @@ break; } } else { - AGCSmoothDoubleExponential(agc_coeffs.agc_pole_z1_, - agc_coeffs.agc_pole_z2_, stage_state); + AGCSmoothDoubleExponential(agc_coeffs.agc_pole_z1, agc_coeffs.agc_pole_z2, + stage_state); } } @@ -284,8 +284,8 @@ } FloatArray Ear::StageGValue(const FloatArray& undamping) { - FloatArray r = car_coeffs_.r1_coeffs_ + car_coeffs_.zr_coeffs_ * undamping; - return (1 - 2 * r * car_coeffs_.a0_coeffs_ + (r * r)) / - (1 - 2 * r * car_coeffs_.a0_coeffs_ + car_coeffs_.h_coeffs_ * r * - car_coeffs_.c0_coeffs_ + (r * r)); + FloatArray r = car_coeffs_.r1_coeffs + car_coeffs_.zr_coeffs * undamping; + return (1 - 2 * r * car_coeffs_.a0_coeffs + (r * r)) / + (1 - 2 * r * car_coeffs_.a0_coeffs + car_coeffs_.h_coeffs * r * + car_coeffs_.c0_coeffs + (r * r)); } \ No newline at end of file