alexbrandmeyer@668: // alexbrandmeyer@668: // car_coeffs.cc alexbrandmeyer@668: // CARFAC Open Source C++ Library alexbrandmeyer@668: // alexbrandmeyer@668: // Created by Alex Brandmeyer on 5/18/13. alexbrandmeyer@668: // Copyright (c) 2013 Alex Brandmeyer. All rights reserved. alexbrandmeyer@668: // alexbrandmeyer@668: alexbrandmeyer@668: #include "car_coeffs.h" alexbrandmeyer@668: alexbrandmeyer@668: void CARCoeffs::Design(const CARParams& car_params, const FPType fs, alexbrandmeyer@668: const FloatArray& pole_freqs) { alexbrandmeyer@668: // TODO (alexbrandmeyer): verify acceptability of/documentation level needed alexbrandmeyer@668: // for use of short intermediate variable names. alexbrandmeyer@668: n_ch_ = pole_freqs.size(); alexbrandmeyer@668: velocity_scale_ = car_params.velocity_scale_; alexbrandmeyer@668: v_offset_ = car_params.v_offset_; alexbrandmeyer@668: r1_coeffs_.resize(n_ch_); alexbrandmeyer@668: a0_coeffs_.resize(n_ch_); alexbrandmeyer@668: c0_coeffs_.resize(n_ch_); alexbrandmeyer@668: h_coeffs_.resize(n_ch_); alexbrandmeyer@668: g0_coeffs_.resize(n_ch_); alexbrandmeyer@668: FPType f = car_params.zero_ratio_ * car_params.zero_ratio_ - 1.0; alexbrandmeyer@668: FloatArray theta = pole_freqs * ((2.0 * PI) / fs); alexbrandmeyer@668: c0_coeffs_ = theta.sin(); alexbrandmeyer@668: a0_coeffs_ = theta.cos(); alexbrandmeyer@668: FPType ff = car_params.high_f_damping_compression_; alexbrandmeyer@668: FloatArray x = theta / PI; alexbrandmeyer@668: zr_coeffs_ = PI * (x - (ff * (x*x*x))); alexbrandmeyer@668: FPType max_zeta = car_params.max_zeta_; alexbrandmeyer@668: FPType min_zeta = car_params.min_zeta_; alexbrandmeyer@668: r1_coeffs_ = (1.0 - (zr_coeffs_ * max_zeta)); alexbrandmeyer@668: FloatArray erb_freqs(n_ch_); alexbrandmeyer@668: for (int ch=0; ch < n_ch_; ++ch) { alexbrandmeyer@668: erb_freqs(ch) = ERBHz(pole_freqs(ch), car_params.erb_break_freq_, alexbrandmeyer@668: car_params.erb_q_); alexbrandmeyer@668: } alexbrandmeyer@668: FloatArray min_zetas = min_zeta + (0.25 * ((erb_freqs / pole_freqs) - alexbrandmeyer@668: min_zeta)); alexbrandmeyer@668: zr_coeffs_ *= max_zeta - min_zetas; alexbrandmeyer@668: h_coeffs_ = c0_coeffs_ * f; alexbrandmeyer@668: FloatArray relative_undamping = FloatArray::Ones(n_ch_); alexbrandmeyer@668: FloatArray r = r1_coeffs_ + (zr_coeffs_ * relative_undamping); alexbrandmeyer@668: g0_coeffs_ = (1.0 - (2.0 * r * a0_coeffs_) + (r*r)) / alexbrandmeyer@668: (1 - (2 * r * a0_coeffs_) + alexbrandmeyer@668: (h_coeffs_ * r * c0_coeffs_) + (r*r)); alexbrandmeyer@668: }