alexbrandmeyer@668
|
1 //
|
alexbrandmeyer@668
|
2 // car_coeffs.cc
|
alexbrandmeyer@668
|
3 // CARFAC Open Source C++ Library
|
alexbrandmeyer@668
|
4 //
|
alexbrandmeyer@668
|
5 // Created by Alex Brandmeyer on 5/18/13.
|
alexbrandmeyer@668
|
6 // Copyright (c) 2013 Alex Brandmeyer. All rights reserved.
|
alexbrandmeyer@668
|
7 //
|
alexbrandmeyer@668
|
8
|
alexbrandmeyer@668
|
9 #include "car_coeffs.h"
|
alexbrandmeyer@668
|
10
|
alexbrandmeyer@668
|
11 void CARCoeffs::Design(const CARParams& car_params, const FPType fs,
|
alexbrandmeyer@668
|
12 const FloatArray& pole_freqs) {
|
alexbrandmeyer@668
|
13 // TODO (alexbrandmeyer): verify acceptability of/documentation level needed
|
alexbrandmeyer@668
|
14 // for use of short intermediate variable names.
|
alexbrandmeyer@668
|
15 n_ch_ = pole_freqs.size();
|
alexbrandmeyer@668
|
16 velocity_scale_ = car_params.velocity_scale_;
|
alexbrandmeyer@668
|
17 v_offset_ = car_params.v_offset_;
|
alexbrandmeyer@668
|
18 r1_coeffs_.resize(n_ch_);
|
alexbrandmeyer@668
|
19 a0_coeffs_.resize(n_ch_);
|
alexbrandmeyer@668
|
20 c0_coeffs_.resize(n_ch_);
|
alexbrandmeyer@668
|
21 h_coeffs_.resize(n_ch_);
|
alexbrandmeyer@668
|
22 g0_coeffs_.resize(n_ch_);
|
alexbrandmeyer@668
|
23 FPType f = car_params.zero_ratio_ * car_params.zero_ratio_ - 1.0;
|
alexbrandmeyer@668
|
24 FloatArray theta = pole_freqs * ((2.0 * PI) / fs);
|
alexbrandmeyer@668
|
25 c0_coeffs_ = theta.sin();
|
alexbrandmeyer@668
|
26 a0_coeffs_ = theta.cos();
|
alexbrandmeyer@668
|
27 FPType ff = car_params.high_f_damping_compression_;
|
alexbrandmeyer@668
|
28 FloatArray x = theta / PI;
|
alexbrandmeyer@668
|
29 zr_coeffs_ = PI * (x - (ff * (x*x*x)));
|
alexbrandmeyer@668
|
30 FPType max_zeta = car_params.max_zeta_;
|
alexbrandmeyer@668
|
31 FPType min_zeta = car_params.min_zeta_;
|
alexbrandmeyer@668
|
32 r1_coeffs_ = (1.0 - (zr_coeffs_ * max_zeta));
|
alexbrandmeyer@668
|
33 FloatArray erb_freqs(n_ch_);
|
alexbrandmeyer@668
|
34 for (int ch=0; ch < n_ch_; ++ch) {
|
alexbrandmeyer@668
|
35 erb_freqs(ch) = ERBHz(pole_freqs(ch), car_params.erb_break_freq_,
|
alexbrandmeyer@668
|
36 car_params.erb_q_);
|
alexbrandmeyer@668
|
37 }
|
alexbrandmeyer@668
|
38 FloatArray min_zetas = min_zeta + (0.25 * ((erb_freqs / pole_freqs) -
|
alexbrandmeyer@668
|
39 min_zeta));
|
alexbrandmeyer@668
|
40 zr_coeffs_ *= max_zeta - min_zetas;
|
alexbrandmeyer@668
|
41 h_coeffs_ = c0_coeffs_ * f;
|
alexbrandmeyer@668
|
42 FloatArray relative_undamping = FloatArray::Ones(n_ch_);
|
alexbrandmeyer@668
|
43 FloatArray r = r1_coeffs_ + (zr_coeffs_ * relative_undamping);
|
alexbrandmeyer@668
|
44 g0_coeffs_ = (1.0 - (2.0 * r * a0_coeffs_) + (r*r)) /
|
alexbrandmeyer@668
|
45 (1 - (2 * r * a0_coeffs_) +
|
alexbrandmeyer@668
|
46 (h_coeffs_ * r * c0_coeffs_) + (r*r));
|
alexbrandmeyer@668
|
47 } |