00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CARFAC.h"
00020
00021 using std::cout;
00022 using std::endl;
00023 using std::ostream;
00024
00025 namespace Marsyas
00026 {
00027
00028 filter_state_class::filter_state_class()
00029 {
00030 init = false;
00031 }
00032
00033 filter_state_class::~filter_state_class()
00034 {
00035 }
00036
00037 std::vector<double> filter_state_class::FilterStep(CF_class &CF, double input_waves, std::vector<double> &filterstep_detect)
00038 {
00039 if (!init) {
00040 filterstep_inputs.resize(CF.n_ch);
00041 filterstep_zA.resize(CF.n_ch);
00042 filterstep_zB.resize(CF.n_ch);
00043 filterstep_zY.resize(CF.n_ch);
00044 filterstep_z1.resize(CF.n_ch);
00045 filterstep_z2.resize(CF.n_ch);
00046 }
00047
00048
00049 filterstep_inputs[0] = input_waves;
00050
00051 for (unsigned int i=0; i < zY_memory.size()-1; i++) {
00052 filterstep_inputs[i+1] = zY_memory[i];
00053 }
00054
00055
00056 for (int i=0; i < CF.n_ch; i++) {
00057 zB_memory[i] = zB_memory[i] + dzB_memory[i];
00058 double filterstep_r = CF.filter_coeffs.r_coeffs[i] - CF.filter_coeffs.c_coeffs[i] * (zA_memory[i] + zB_memory[i]);
00059
00060
00061
00062 double z1_mem = z1_memory[i];
00063 z1_memory[i] = ((filterstep_r *
00064 (CF.filter_coeffs.a_coeffs[i] * z1_memory[i] -
00065 CF.filter_coeffs.c_coeffs[i] * z2_memory[i]))
00066 + filterstep_inputs[i]);
00067 z2_memory[i] = filterstep_r * (CF.filter_coeffs.c_coeffs[i] * z1_mem +
00068 CF.filter_coeffs.a_coeffs[i] * z2_memory[i]);
00069 }
00070
00071
00072 for (int i=0; i<CF.n_ch; i++) {
00073 zA_memory[i] = pow(((z2_memory[i] - z2_memory[i]) * CF.filter_coeffs.velocity_scale), 2);
00074 }
00075
00076 for (int i=0; i<CF.n_ch; i++) {
00077
00078 zA_memory[i] = (1 - pow((1 - zA_memory[i]), 4)) / 4;
00079
00080 zY_memory[i] = CF.filter_coeffs.g_coeffs[i] * (filterstep_inputs[i] + CF.filter_coeffs.h_coeffs[i] * z2_memory[i]);
00081 }
00082
00083
00084 double maxval = 0.0;
00085 for (int i=0; i<CF.n_ch; i++) {
00086 filterstep_detect[i] = zY_memory[i] > maxval ? zY_memory[i] : maxval;
00087 }
00088
00089 for (int i=0; i<CF.n_ch; i++) {
00090 double output = zY_memory[i];
00091 double detect = output > 0.0 ? output : 0.0;
00092 filterstep_detect[i] = detect;
00093 detect_accum[i] += detect;
00094 }
00095
00096 return filterstep_detect;
00097 }
00098
00099
00100 ostream& operator<<(ostream& o, std::vector<double> a)
00101 {
00102 int max_x = (a.size() < 5) ? a.size() : 5;
00103 for (int i=0; i<max_x; i++) {
00104 o << a[i] << " ";
00105 }
00106 return o;
00107 }
00108
00109 ostream& operator<<(ostream& o, std::vector<std::vector<double> > a)
00110 {
00111 int max_x = (a.size() < 5) ? a.size() : 5;
00112 int max_y = (a[0].size() < 5) ? a[0].size() : 5;
00113 for (int i=0; i<max_x; i++) {
00114 for (int j=0; j<max_y; j++) {
00115 o << a[i][j] << " ";
00116 }
00117 o << endl << "\t\t\t";
00118 }
00119 return o;
00120 }
00121
00122 ostream& operator<<(ostream& o, const filter_state_class& l)
00123 {
00124 o << "\tz1_memory=" << l.z1_memory << endl;
00125 o << "\tz2_memory=" << l.z2_memory << endl;
00126 o << "\tzA_memory=" << l.zA_memory << endl;
00127 o << "\tzB_memory=" << l.zB_memory << endl;
00128 o << "\tdzB_memory=" << l.dzB_memory << endl;
00129 o << "\tzY_memory=" << l.zY_memory << endl;
00130 o << "\tdetect_accum=" << l.detect_accum << endl;
00131
00132 return o;
00133 }
00134
00136
00137 AGC_state_class::AGC_state_class()
00138 {
00139 }
00140
00141 AGC_state_class::~AGC_state_class()
00142 {
00143 }
00144
00145 ostream& operator<<(ostream& o, const AGC_state_class& l)
00146 {
00147 o << "**AGC_state_class" << endl;
00148 o << "\tsum_AGC=" << l.sum_AGC << endl;
00149
00150 for (int i = 0; i < 4; i++) {
00151 o << "\tAGC_memory(" << i << ")=";
00152 for (int j = 0; j < 5; j++) {
00153 o << l.AGC_memory[j][i] << " ";
00154 }
00155 o << endl;
00156 }
00157 return o;
00158 }
00159
00161
00162 strobe_state_class::strobe_state_class()
00163 {
00164 }
00165
00166 strobe_state_class::~strobe_state_class()
00167 {
00168 }
00169
00170 ostream& operator<<(ostream& o, const strobe_state_class& l)
00171 {
00172 o << "**strobe_state_class" << endl;
00173 o << "\tlastdata=" << l.lastdata << endl;
00174 o << "\tthresholds=" << l.thresholds << endl;
00175
00176
00177
00178 return o;
00179 }
00180
00182
00183 filter_coeffs_class::filter_coeffs_class()
00184 {
00185 }
00186
00187 filter_coeffs_class::~filter_coeffs_class()
00188 {
00189 }
00190
00191 void filter_coeffs_class::init(double v, int n_ch)
00192 {
00193 velocity_scale = v;
00194
00195 r_coeffs.assign(n_ch,0);
00196 a_coeffs.assign(n_ch,0);
00197 c_coeffs.assign(n_ch,0);
00198 h_coeffs.assign(n_ch,0);
00199 g_coeffs.assign(n_ch,0);
00200
00201 }
00202
00203 ostream& operator<<(ostream& o, const filter_coeffs_class& l)
00204 {
00205 o << "**filter_coeffs_class" << endl;
00206 o << "\t\tvelocity_scale=" << l.velocity_scale << endl;
00207
00208 o << "\t\tr_coeffs=" << l.r_coeffs << endl;
00209 o << "\t\ta_coeffs=" << l.a_coeffs << endl;
00210 o << "\t\tc_coeffs=" << l.c_coeffs << endl;
00211 o << "\t\th_coeffs=" << l.h_coeffs << endl;
00212 o << "\t\tg_coeffs=" << l.g_coeffs << endl;
00213
00214 return o;
00215 }
00216
00217
00219
00220 CF_AGC_params_class::CF_AGC_params_class()
00221 {
00222 n_stages = 4;
00223 time_constants.push_back(1*0.002);
00224 time_constants.push_back(4*0.002);
00225 time_constants.push_back(16*0.002);
00226 time_constants.push_back(64*0.002);
00227
00228 AGC_stage_gain = 2;
00229 decimation = 16;
00230
00231 AGC1_scales.push_back(1*1);
00232 AGC1_scales.push_back(2*1);
00233 AGC1_scales.push_back(3*1);
00234 AGC1_scales.push_back(4*1);
00235
00236 AGC2_scales.push_back(1*1.5);
00237 AGC2_scales.push_back(2*1.5);
00238 AGC2_scales.push_back(3*1.5);
00239 AGC2_scales.push_back(4*1.5);
00240
00241 detect_scale = 0.002;
00242 AGC_mix_coeff = 0.25;
00243 }
00244
00245
00246 CF_AGC_params_class::~CF_AGC_params_class()
00247 {
00248 }
00249
00250 ostream& operator<<(ostream& o, const CF_AGC_params_class& l)
00251 {
00252 o << "**CF_AGC_params_class" << endl;
00253 o << "\t\tn_stages=" << l.n_stages << endl;
00254
00255 o << "\t\ttime_constants=[";
00256 for (unsigned int i=0; i<l.time_constants.size(); i++) {
00257 o << l.time_constants[i] << " ";
00258 }
00259 o << "]" << endl;
00260
00261 o << "\t\tAGC_stage_gain=" << l.AGC_stage_gain << endl;
00262 o << "\t\tdecimation=" << l.decimation << endl;
00263
00264 o << "\t\tAGC1_scales=";
00265 for (unsigned int i=0; i<l.AGC1_scales.size(); i++) {
00266 o << l.AGC1_scales[i] << " ";
00267 }
00268 o << endl;
00269
00270 o << "\t\tAGC2_scales=";
00271 for (unsigned int i=0; i<l.AGC2_scales.size(); i++) {
00272 o << l.AGC2_scales[i] << " ";
00273 }
00274 o << endl;
00275
00276 o << "\t\tdetect_scale=" << l.detect_scale << endl;
00277 o << "\t\tAGC_mix_coeff=" << l.AGC_mix_coeff << endl;
00278
00279 return o;
00280 }
00281
00283
00284 AGC_coeffs_class::AGC_coeffs_class()
00285 {
00286 }
00287
00288 AGC_coeffs_class::~AGC_coeffs_class()
00289 {
00290 }
00291
00292 ostream& operator<<(ostream& o, const AGC_coeffs_class& l)
00293 {
00294 o << "**AGC_coeffs_class" << endl;
00295 o << "\t\tdetect_scale=" << l.detect_scale << endl;
00296 o << "\t\tAGC_stage_gain=" << l.AGC_stage_gain << endl;
00297 o << "\t\tAGC_mix_coeff=" << l.AGC_mix_coeff << endl;
00298 o << "\t\tAGC_epsilon=[";
00299 for (unsigned int i=0; i<l.AGC_epsilon.size(); i++) {
00300 o << l.AGC_epsilon[i] << " ";
00301 }
00302 o << "]" << endl;
00303
00304 return o;
00305 }
00306
00308
00309 CF_filter_params_class::CF_filter_params_class()
00310 {
00311 velocity_scale = 0.002;
00312 min_zeta = 0.15;
00313 first_pole_theta = 0.78 * PI;
00314 zero_ratio = sqrt((float)2.0);
00315 ERB_per_step = 0.3333;
00316 min_pole_Hz = 40;
00317 }
00318
00319 CF_filter_params_class::~CF_filter_params_class()
00320 {
00321 }
00322
00323
00324 ostream& operator<<(ostream& o, const CF_filter_params_class& l)
00325 {
00326 o << "**CF_filter_params_class" << endl;
00327 o << "\t\tvelocity_scale=" << l.velocity_scale << endl;
00328 o << "\t\tmin_zeta=" << l.min_zeta << endl;
00329 o << "\t\tfirst_pole_theta=" << l.first_pole_theta << endl;
00330 o << "\t\tzero_ratio=" << l.zero_ratio << endl;
00331 o << "\t\tERB_per_step=" << l.ERB_per_step << endl;
00332 o << "\t\tmin_pole_Hz=" << l.min_pole_Hz << endl;
00333 return o;
00334 }
00335
00337
00338 CF_class::CF_class()
00339 {
00340 CARFAC_Design();
00341
00342
00343 n_mics = 2;
00344 }
00345
00346 CF_class::~CF_class()
00347 {
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 void CF_class::CARFAC_Design(double _fs, double _ERB_break_freq, double _ERB_Q)
00375 {
00376 AGC_coeffs.detect_scale = CF_AGC_params.detect_scale;
00377 AGC_coeffs.AGC_stage_gain = CF_AGC_params.AGC_stage_gain;
00378 AGC_coeffs.AGC_mix_coeff = CF_AGC_params.AGC_mix_coeff;
00379
00380
00381
00382
00383 if (_fs == -1) {
00384 fs = 22050;
00385 }
00386
00387
00388 double pole_Hz = CF_filter_params.first_pole_theta * fs / (2 * PI);
00389 n_ch = 0;
00390 while (pole_Hz > CF_filter_params.min_pole_Hz) {
00391 n_ch = n_ch + 1;
00392 pole_Hz = pole_Hz - CF_filter_params.ERB_per_step * ERB_Hz(pole_Hz, _ERB_break_freq, _ERB_Q);
00393 }
00394
00395 pole_freqs.assign(n_ch,0);
00396 pole_Hz = CF_filter_params.first_pole_theta * fs / (2 * PI);
00397 for(int ch = 0; ch < n_ch; ch++) {
00398 pole_freqs[ch] = pole_Hz;
00399 pole_Hz = pole_Hz - CF_filter_params.ERB_per_step * ERB_Hz(pole_Hz, _ERB_break_freq, _ERB_Q);
00400 }
00401
00402
00403 CARFAC_DesignFilters();
00404 CARFAC_DesignAGC();
00405 }
00406
00407
00408 double CF_class::ERB_Hz(double CF_Hz, double ERB_break_freq, double ERB_Q)
00409 {
00410 if (ERB_Q == -1) {
00411 ERB_Q = 1000/(24.7*4.37);
00412 }
00413
00414 if (ERB_break_freq == -1) {
00415 ERB_break_freq = 1000/4.37;
00416 }
00417
00418 double ERB = (ERB_break_freq + CF_Hz) / ERB_Q;
00419 return ERB;
00420 }
00421
00422
00423
00424 void CF_class::CARFAC_DesignFilters()
00425 {
00426 int n_ch = pole_freqs.size();
00427
00428 filter_coeffs.init(CF_filter_params.velocity_scale, n_ch);
00429
00430
00431
00432
00433
00434 double f = pow(CF_filter_params.zero_ratio,2) - 1;
00435
00436
00437
00438 std::vector<double> theta(n_ch);
00439 for (unsigned int i = 0; i < theta.size(); i++) {
00440 theta[i] = pole_freqs[i] * (2 * PI / fs);
00441 }
00442
00443
00444
00445 std::vector<double> r(n_ch);
00446 for (unsigned int i = 0; i < r.size(); i++) {
00447 r[i] = (1 - (sin(theta[i]) * CF_filter_params.min_zeta));
00448 }
00449 filter_coeffs.r_coeffs = r;
00450
00451
00452 for (unsigned int i = 0; i < theta.size(); i++) {
00453 filter_coeffs.a_coeffs[i] = cos(theta[i]);
00454 filter_coeffs.c_coeffs[i] = sin(theta[i]);
00455 }
00456
00457
00458 std::vector<double> h(n_ch);
00459 for (unsigned int i = 0; i < theta.size(); i++) {
00460 h[i] = sin(theta[i]) * f;
00461 }
00462 filter_coeffs.h_coeffs = h;
00463
00464
00465 std::vector<double> r2 = r;
00466 for (unsigned int i = 0; i < theta.size(); i++) {
00467 filter_coeffs.g_coeffs[i] =
00468 1 / (1 + h[i] * r2[i] * sin(theta[i]) / (1 - 2 * r2[i] * cos(theta[i]) + pow(r2[i], 2)));
00469 }
00470 }
00471
00472
00473 void CF_class::CARFAC_DesignAGC()
00474 {
00475 std::vector<double> AGC1_scales = CF_AGC_params.AGC1_scales;
00476 std::vector<double> AGC2_scales = CF_AGC_params.AGC2_scales;
00477
00478 int n_AGC_stages = CF_AGC_params.n_stages;
00479 AGC_coeffs.AGC_epsilon.assign(n_AGC_stages, 0);
00480 AGC_coeffs.AGC1_polez.assign(n_AGC_stages, 0);
00481 AGC_coeffs.AGC2_polez.assign(n_AGC_stages, 0);
00482 int decim = CF_AGC_params.decimation;
00483
00484 for (int stage = 0; stage < n_AGC_stages; stage++) {
00485 double tau = CF_AGC_params.time_constants[stage];
00486
00487
00488 AGC_coeffs.AGC_epsilon[stage] = 1 - exp(-decim / (tau * fs));
00489
00490
00491 double ntimes = tau * (fs / decim);
00492
00493
00494 double t = (pow(AGC1_scales[stage],2)) / ntimes;
00495 AGC_coeffs.AGC1_polez[stage] = 1 + 1/t - sqrt(pow(1+1/t,2) - 1);
00496 t = (pow(AGC2_scales[stage],2)) / ntimes;
00497 AGC_coeffs.AGC2_polez[stage] = 1 + 1/t - sqrt(pow(1+1/t,2) - 1);
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 void CF_class::CARFAC_Init(int n_mics)
00516 {
00517 std::vector<double> AGC_time_constants = CF_AGC_params.time_constants;
00518 int n_AGC_stages = AGC_time_constants.size();
00519 filter_state_class tmp_filter_state;
00520 tmp_filter_state.z1_memory.assign(n_ch,0.0);
00521 tmp_filter_state.z2_memory.assign(n_ch,0.0);
00522 tmp_filter_state.zA_memory.assign(n_ch,0.0);
00523 tmp_filter_state.zB_memory.assign(n_ch,0.0);
00524 tmp_filter_state.dzB_memory.assign(n_ch,0.0);
00525 tmp_filter_state.zY_memory.assign(n_ch,0.0);
00526 tmp_filter_state.detect_accum.assign(n_ch,0.0);
00527
00528 for (int mic = 0; mic < n_mics; mic++) {
00529 filter_state.push_back(tmp_filter_state);
00530 }
00531
00532
00533 AGC_state_class tmp_AGC_state;
00534 tmp_AGC_state.sum_AGC.assign(n_ch,0.0);
00535
00536 std::vector<double> tmp_AGC_memory(n_ch);
00537 for (int i = 0; i < n_AGC_stages; i++) {
00538 tmp_AGC_state.AGC_memory.push_back(tmp_AGC_memory);
00539 }
00540
00541 for (int mic = 0; mic < n_mics; mic++) {
00542 AGC_state.push_back(tmp_AGC_state);
00543 }
00544
00545
00546 strobe_threshold_start = 0.0100;
00547 strobe_state_class tmp_strobe_state;
00548 tmp_strobe_state.lastdata.assign(n_ch,0.0);
00549 tmp_strobe_state.thresholds.assign(n_ch,strobe_threshold_start);
00550 tmp_strobe_state.trigger_index.assign(n_ch,0);
00551 tmp_strobe_state.sai_index.assign(n_ch,0);
00552
00553 for (int mic = 0; mic < n_mics; mic++) {
00554 strobe_state.push_back(tmp_strobe_state);
00555 }
00556
00557 }
00558
00559 ostream& operator<<(ostream& o, const CF_class& l)
00560 {
00561 o << "*CF_class" << endl;
00562 if (l.printcoeffs) {
00563 o << "\tfs=" << l.fs << endl;
00564 o << "\tn_ch=" << l.n_ch << endl;
00565 o << "\tn_mics=" << l.n_mics << endl;
00566 o << "\tCF_filter_params=" << l.CF_filter_params << endl;
00567 o << "\tCF_AGC_params=" << l.CF_AGC_params << endl;
00568 o << "\tfilter_coeffs=" << l.filter_coeffs << endl;
00569 o << "\tAGC_coeffs=" << l.AGC_coeffs << endl;
00570 }
00571
00572 if (l.printstate) {
00573 for (unsigned int i=0; i<l.filter_state.size(); i++) {
00574 o << "filter_state(" << i+1 << ")" << endl;
00575 o << l.filter_state[i];
00576
00577 o << "AGC_state(" << i+1 << ")" << endl;
00578 o << l.AGC_state[i];
00579 }
00580 }
00581
00582 return o;
00583 }
00584 }