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;