Mercurial > hg > aimc
comparison src/Modules/BMM/ModulePZFC.cc @ 47:2204b3a05a28
-Reinstated original parameter-setting
author | tomwalters |
---|---|
date | Mon, 07 Jun 2010 08:34:49 +0000 |
parents | c5f5e9569863 |
children | c5ac2f0c7fc5 |
comparison
equal
deleted
inserted
replaced
46:c8024714e13e | 47:2204b3a05a28 |
---|---|
48 0.11f); | 48 0.11f); |
49 min_bandwidth_hz_ = parameters_->DefaultFloat("pzfc.min_bandwidth_hz", | 49 min_bandwidth_hz_ = parameters_->DefaultFloat("pzfc.min_bandwidth_hz", |
50 27.0f); | 50 27.0f); |
51 agc_factor_ = parameters_->DefaultFloat("pzfc.agc_factor", 12.0f); | 51 agc_factor_ = parameters_->DefaultFloat("pzfc.agc_factor", 12.0f); |
52 do_agc_step_ = parameters_->DefaultBool("pzfc.do_agc", true); | 52 do_agc_step_ = parameters_->DefaultBool("pzfc.do_agc", true); |
53 use_fitted_parameters_ = parameters_->DefaultBool("pzfc.use_fit", false); | |
53 | 54 |
54 detect_.resize(0); | 55 detect_.resize(0); |
55 } | 56 } |
56 | 57 |
57 ModulePZFC::~ModulePZFC() { | 58 ModulePZFC::~ModulePZFC() { |
114 } | 115 } |
115 | 116 |
116 last_input_ = 0.0f; | 117 last_input_ = 0.0f; |
117 } | 118 } |
118 | 119 |
120 bool ModulePZFC::SetPZBankCoeffsOrig() { | |
121 // This function sets the following variables: | |
122 // channel_count_ | |
123 // pole_dampings_ | |
124 // pole_frequencies_ | |
125 // za0_, za1_, za2 | |
126 // output_ | |
127 | |
128 // TODO(tomwalters): There's significant code-duplication between this function | |
129 // and SetPZBankCoeffsERBFitted, and SetPZBankCoeffs | |
130 | |
131 // Normalised maximum pole frequency | |
132 float pole_frequency = cf_max_ / sample_rate_ * (2.0f * M_PI); | |
133 channel_count_ = 0; | |
134 while ((pole_frequency / (2.0f * M_PI)) * sample_rate_ > cf_min_) { | |
135 float bw = bandwidth_over_cf_ * pole_frequency + 2 * M_PI * min_bandwidth_hz_ / sample_rate_; | |
136 pole_frequency -= step_factor_ * bw; | |
137 channel_count_++; | |
138 } | |
139 | |
140 // Now the number of channels is known, various buffers for the filterbank | |
141 // coefficients can be initialised | |
142 pole_dampings_.clear(); | |
143 pole_dampings_.resize(channel_count_, pole_damping_); | |
144 pole_frequencies_.clear(); | |
145 pole_frequencies_.resize(channel_count_, 0.0f); | |
146 | |
147 // Direct-form coefficients | |
148 za0_.clear(); | |
149 za0_.resize(channel_count_, 0.0f); | |
150 za1_.clear(); | |
151 za1_.resize(channel_count_, 0.0f); | |
152 za2_.clear(); | |
153 za2_.resize(channel_count_, 0.0f); | |
154 | |
155 // The output signal bank | |
156 output_.Initialize(channel_count_, buffer_length_, sample_rate_); | |
157 | |
158 // Reset the pole frequency to maximum | |
159 pole_frequency = cf_max_ / sample_rate_ * (2.0f * M_PI); | |
160 | |
161 for (int i = channel_count_ - 1; i > -1; --i) { | |
162 // Store the normalised pole frequncy | |
163 pole_frequencies_[i] = pole_frequency; | |
164 | |
165 // Calculate the real pole frequency from the normalised pole frequency | |
166 float frequency = pole_frequency / (2.0f * M_PI) * sample_rate_; | |
167 | |
168 // Store the real pole frequency as the 'centre frequency' of the filterbank | |
169 // channel | |
170 output_.set_centre_frequency(i, frequency); | |
171 | |
172 float zero_frequency = Minimum(M_PI, zero_factor_ * pole_frequency); | |
173 | |
174 // Impulse-invariance mapping | |
175 float z_plane_theta = zero_frequency * sqrt(1.0f - pow(zero_damping_, 2)); | |
176 float z_plane_rho = exp(-zero_damping_ * zero_frequency); | |
177 | |
178 // Direct-form coefficients from z-plane rho and theta | |
179 float a1 = -2.0f * z_plane_rho * cos(z_plane_theta); | |
180 float a2 = z_plane_rho * z_plane_rho; | |
181 | |
182 // Normalised to unity gain at DC | |
183 float a_sum = 1.0f + a1 + a2; | |
184 za0_[i] = 1.0f / a_sum; | |
185 za1_[i] = a1 / a_sum; | |
186 za2_[i] = a2 / a_sum; | |
187 | |
188 // Subtract step factor (1/n2) times current bandwidth from the pole | |
189 // frequency | |
190 float bw = bandwidth_over_cf_ * pole_frequency + 2 * M_PI * min_bandwidth_hz_ / sample_rate_; | |
191 pole_frequency -= step_factor_ * bw; | |
192 } | |
193 return true; | |
194 } | |
195 | |
196 | |
197 bool ModulePZFC::SetPZBankCoeffsERB() { | |
198 // This function sets the following variables: | |
199 // channel_count_ | |
200 // pole_dampings_ | |
201 // pole_frequencies_ | |
202 // za0_, za1_, za2 | |
203 // output_ | |
204 | |
205 // TODO(tomwalters): There's significant code-duplication between here, | |
206 // SetPZBankCoeffsERBFitted, and SetPZBankCoeffs | |
207 | |
208 // Normalised maximum pole frequency | |
209 float pole_frequency = cf_max_ / sample_rate_ * (2.0f * M_PI); | |
210 channel_count_ = 0; | |
211 while ((pole_frequency / (2.0f * M_PI)) * sample_rate_ > cf_min_) { | |
212 float bw = ERBTools::Freq2ERBw(pole_frequency | |
213 / (2.0f * M_PI) * sample_rate_); | |
214 pole_frequency -= step_factor_ * (bw * (2.0f * M_PI) / sample_rate_); | |
215 channel_count_++; | |
216 } | |
217 | |
218 // Now the number of channels is known, various buffers for the filterbank | |
219 // coefficients can be initialised | |
220 pole_dampings_.clear(); | |
221 pole_dampings_.resize(channel_count_, pole_damping_); | |
222 pole_frequencies_.clear(); | |
223 pole_frequencies_.resize(channel_count_, 0.0f); | |
224 | |
225 // Direct-form coefficients | |
226 za0_.clear(); | |
227 za0_.resize(channel_count_, 0.0f); | |
228 za1_.clear(); | |
229 za1_.resize(channel_count_, 0.0f); | |
230 za2_.clear(); | |
231 za2_.resize(channel_count_, 0.0f); | |
232 | |
233 // The output signal bank | |
234 output_.Initialize(channel_count_, buffer_length_, sample_rate_); | |
235 | |
236 // Reset the pole frequency to maximum | |
237 pole_frequency = cf_max_ / sample_rate_ * (2.0f * M_PI); | |
238 | |
239 for (int i = channel_count_ - 1; i > -1; --i) { | |
240 // Store the normalised pole frequncy | |
241 pole_frequencies_[i] = pole_frequency; | |
242 | |
243 // Calculate the real pole frequency from the normalised pole frequency | |
244 float frequency = pole_frequency / (2.0f * M_PI) * sample_rate_; | |
245 | |
246 // Store the real pole frequency as the 'centre frequency' of the filterbank | |
247 // channel | |
248 output_.set_centre_frequency(i, frequency); | |
249 | |
250 float zero_frequency = Minimum(M_PI, zero_factor_ * pole_frequency); | |
251 | |
252 // Impulse-invariance mapping | |
253 float z_plane_theta = zero_frequency * sqrt(1.0f - pow(zero_damping_, 2)); | |
254 float z_plane_rho = exp(-zero_damping_ * zero_frequency); | |
255 | |
256 // Direct-form coefficients from z-plane rho and theta | |
257 float a1 = -2.0f * z_plane_rho * cos(z_plane_theta); | |
258 float a2 = z_plane_rho * z_plane_rho; | |
259 | |
260 // Normalised to unity gain at DC | |
261 float a_sum = 1.0f + a1 + a2; | |
262 za0_[i] = 1.0f / a_sum; | |
263 za1_[i] = a1 / a_sum; | |
264 za2_[i] = a2 / a_sum; | |
265 | |
266 float bw = ERBTools::Freq2ERBw(pole_frequency | |
267 / (2.0f * M_PI) * sample_rate_); | |
268 pole_frequency -= step_factor_ * (bw * (2.0f * M_PI) / sample_rate_); | |
269 } | |
270 return true; | |
271 } | |
272 | |
119 bool ModulePZFC::SetPZBankCoeffsERBFitted() { | 273 bool ModulePZFC::SetPZBankCoeffsERBFitted() { |
274 //float parameter_values[3 * 7] = { | |
275 //// Filed, Nfit = 524, 11-3 parameters, PZFC, cwt 0, fit time 9915 sec | |
276 //1.14827, 0.00000, 0.00000, // % SumSqrErr= 10125.41 | |
277 //0.53571, -0.70128, 0.63246, // % RMSErr = 2.81586 | |
278 //0.76779, 0.00000, 0.00000, // % MeanErr = 0.00000 | |
279 //// Inf 0.00000 0.00000 % RMSCost = NaN | |
280 //0.00000, 0.00000, 0.00000, | |
281 //6.00000, 0.00000, 0.00000, | |
282 //1.08869, -0.09470, 0.07844, | |
283 //10.56432, 2.52732, 1.86895 | |
284 //// -3.45865 -1.31457 3.91779 % Kv | |
285 //}; | |
286 | |
120 float parameter_values[3 * 7] = { | 287 float parameter_values[3 * 7] = { |
121 // Filed, Nfit = 524, 11-3 parameters, PZFC, cwt 0, fit time 9915 sec | 288 // Fit 515 from Dick |
122 1.14827, 0.00000, 0.00000, // % SumSqrErr= 10125.41 | 289 // Final, Nfit = 515, 9-3 parameters, PZFC, cwt 0 |
123 0.53571, -0.70128, 0.63246, // % RMSErr = 2.81586 | 290 1.72861, 0.00000, 0.00000, // SumSqrErr = 13622.24 |
124 0.76779, 0.00000, 0.00000, // % MeanErr = 0.00000 | 291 0.56657, -0.93911, 0.89163, // RMSErr = 3.26610 |
125 // Inf 0.00000 0.00000 % RMSCost = NaN | 292 0.39469, 0.00000, 0.00000, // MeanErr = 0.00000 |
126 0.00000, 0.00000, 0.00000, | 293 // Inf, 0.00000, 0.00000, // RMSCost = NaN - would set coefc to infinity, but this isn't passed on |
127 6.00000, 0.00000, 0.00000, | 294 0.00000, 0.00000, 0.00000, |
128 1.08869, -0.09470, 0.07844, | 295 2.00000, 0.00000, 0.00000, // |
129 10.56432, 2.52732, 1.86895 | 296 1.27393, 0.00000, 0.00000, |
130 // -3.45865 -1.31457 3.91779 % Kv | 297 11.46247, 5.46894, 0.11800 |
298 // -4.15525, 1.54874, 2.99858 // Kv | |
131 }; | 299 }; |
132 | 300 |
133 // Precalculate the number of channels required - this method is ugly but it | 301 // Precalculate the number of channels required - this method is ugly but it |
134 // was the quickest way of converting from MATLAB as the step factor between | 302 // was the quickest way of converting from MATLAB as the step factor between |
135 // channels can vary quadratically with pole frequency... | 303 // channels can vary quadratically with pole frequency... |
251 } | 419 } |
252 | 420 |
253 bool ModulePZFC::SetPZBankCoeffs() { | 421 bool ModulePZFC::SetPZBankCoeffs() { |
254 /*! \todo Re-implement the alternative parameter settings | 422 /*! \todo Re-implement the alternative parameter settings |
255 */ | 423 */ |
256 if (!SetPZBankCoeffsERBFitted()) | 424 if (use_fitted_parameters_) { |
257 return false; | 425 if (!SetPZBankCoeffsERBFitted()) |
426 return false; | |
427 } else { | |
428 if (!SetPZBankCoeffsOrig()) | |
429 return false; | |
430 } | |
258 | 431 |
259 /*! \todo Make fMindamp and fMaxdamp user-settable? | 432 /*! \todo Make fMindamp and fMaxdamp user-settable? |
260 */ | 433 */ |
261 mindamp_ = 0.18f; | 434 mindamp_ = 0.18f; |
262 maxdamp_ = 0.4f; | 435 maxdamp_ = 0.4f; |