00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "AimSAI.h"
00020
00021 using std::ostringstream;
00022 using namespace Marsyas;
00023
00024 AimSAI::AimSAI(mrs_string name):MarSystem("AimSAI",name)
00025 {
00026 is_initialized = false;
00027 initialized_israte = 0;
00028 initialized_inobservations = 0;
00029 initialized_insamples = 0;
00030 initialized_frame_period_ms = 0.0;
00031 initialized_min_delay_ms = 0.0;
00032 initialized_max_delay_ms = 0.0;
00033 initialized_buffer_memory_decay = 0.0;
00034 initialized_max_concurrent_strobes = 0;
00035 initialized_strobe_weight_alpha = 0.0;
00036
00037 is_reset = false;
00038 reseted_israte = 0;
00039 reseted_inobservations = 0;
00040 reseted_frame_period_ms = 0;
00041
00042 addControls();
00043
00044
00045 min_strobe_delay_idx_ = 0;
00046 max_strobe_delay_idx_ = 0;
00047 sai_decay_factor_ = 0.0;
00048 fire_counter_ = 0;
00049 }
00050
00051 AimSAI::~AimSAI()
00052 {
00053 }
00054
00055 MarSystem*
00056 AimSAI::clone() const
00057 {
00058 return new AimSAI(*this);
00059 }
00060
00061 void
00062 AimSAI::addControls()
00063 {
00064 addControl("mrs_real/min_delay_ms_", 0.0 , ctrl_min_delay_ms_);
00065 addControl("mrs_real/max_delay_ms_", 11.63266, ctrl_max_delay_ms_);
00066 addControl("mrs_real/strobe_weight_alpha_", 0.5 , ctrl_strobe_weight_alpha_);
00067 addControl("mrs_real/buffer_memory_decay_;", 0.03 , ctrl_buffer_memory_decay_);
00068 addControl("mrs_real/frame_period_ms_ ", 11.63266 , ctrl_frame_period_ms_);
00069 addControl("mrs_natural/max_concurrent_strobes_;", 50 , ctrl_max_concurrent_strobes_);
00070 }
00071
00072 void
00073 AimSAI::myUpdate(MarControlPtr sender)
00074 {
00075 int temp_frame_period_samples = (int)(1 + floor(ctrl_israte_->to<mrs_real>() * ctrl_frame_period_ms_->to<mrs_real>()
00076 / 1000.0));
00077 MRSDIAG("AimSAI.cpp - AimSAI:myUpdate");
00078
00079 (void) sender;
00080 ctrl_onSamples_->setValue(temp_frame_period_samples, NOUPDATE);
00081 ctrl_osrate_->setValue(ctrl_israte_->to<mrs_real>(), NOUPDATE);
00082 ctrl_onObsNames_->setValue("AimSAI_" + ctrl_inObsNames_->to<mrs_string>() , NOUPDATE);
00083
00084
00085
00086
00087
00088 channel_count_ = ctrl_inObservations_->to<mrs_natural>() / 3;
00089 ctrl_onObservations_->setValue(channel_count_, NOUPDATE);
00090
00091
00092
00093
00094 if (initialized_israte != ctrl_israte_->to<mrs_real>() ||
00095 initialized_inobservations != ctrl_inObservations_->to<mrs_natural>() ||
00096 initialized_insamples != ctrl_inSamples_->to<mrs_natural>() ||
00097 initialized_frame_period_ms != ctrl_frame_period_ms_->to<mrs_real>() ||
00098 initialized_min_delay_ms != ctrl_min_delay_ms_->to<mrs_real>() ||
00099 initialized_max_delay_ms != ctrl_max_delay_ms_->to<mrs_real>() ||
00100 initialized_buffer_memory_decay != ctrl_buffer_memory_decay_->to<mrs_real>() ||
00101 initialized_max_concurrent_strobes != ctrl_max_concurrent_strobes_->to<mrs_natural>() ||
00102 initialized_strobe_weight_alpha != ctrl_strobe_weight_alpha_->to<mrs_real>()) {
00103 is_initialized = false;
00104 }
00105
00106 if (!is_initialized) {
00107 InitializeInternal();
00108 is_initialized = true;
00109 initialized_israte = ctrl_israte_->to<mrs_real>();
00110 initialized_inobservations = ctrl_inObservations_->to<mrs_natural>();
00111 initialized_insamples = ctrl_inSamples_->to<mrs_natural>();
00112 initialized_frame_period_ms = ctrl_frame_period_ms_->to<mrs_real>();
00113 initialized_min_delay_ms = ctrl_min_delay_ms_->to<mrs_real>();
00114 initialized_max_delay_ms = ctrl_max_delay_ms_->to<mrs_real>();
00115 initialized_buffer_memory_decay = ctrl_buffer_memory_decay_->to<mrs_real>();
00116 initialized_max_concurrent_strobes = ctrl_max_concurrent_strobes_->to<mrs_natural>();
00117 initialized_strobe_weight_alpha = ctrl_strobe_weight_alpha_->to<mrs_real>();
00118 }
00119
00120
00121
00122
00123 if (reseted_israte != ctrl_israte_->to<mrs_real>() ||
00124 reseted_inobservations != ctrl_inObservations_->to<mrs_natural>() ||
00125 reseted_frame_period_ms != ctrl_frame_period_ms_->to<mrs_real>()) {
00126 is_reset = false;
00127 }
00128
00129 if (!is_reset) {
00130 ResetInternal();
00131 is_reset = true;
00132 reseted_israte = ctrl_israte_->to<mrs_real>();
00133 reseted_inobservations = ctrl_inObservations_->to<mrs_natural>();
00134 reseted_frame_period_ms = ctrl_frame_period_ms_->to<mrs_real>();
00135 }
00136
00137 }
00138
00139 void
00140 AimSAI::InitializeInternal() {
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 centre_frequencies_.resize(channel_count_);
00169
00170 int temp_frame_period_samples = (int)(1 + floor(ctrl_israte_->to<mrs_real>() * ctrl_frame_period_ms_->to<mrs_real>()
00171 / 1000.0));
00172 sai_temp_.create(channel_count_,temp_frame_period_samples);
00173
00174 frame_period_samples_ = (mrs_real)floor(ctrl_israte_->to<mrs_real>() * ctrl_frame_period_ms_->to<mrs_real>()
00175 / 1000.0);
00176 min_strobe_delay_idx_ = (mrs_real)floor(ctrl_israte_->to<mrs_real>() * ctrl_min_delay_ms_->to<mrs_real>()
00177 / 1000.0);
00178 max_strobe_delay_idx_ = (mrs_real)floor(ctrl_israte_->to<mrs_real>() * ctrl_max_delay_ms_->to<mrs_real>()
00179 / 1000.0);
00180
00181
00182 if (max_strobe_delay_idx_ > ctrl_onSamples_->to<mrs_natural>()) {
00183 max_strobe_delay_idx_ = ctrl_onSamples_->to<mrs_natural>();
00184 }
00185
00186
00187 sai_decay_factor_ = pow(0.5, 1.0 / (double)(ctrl_buffer_memory_decay_->to<mrs_real>() * (double)ctrl_israte_->to<mrs_real>()));
00188
00189
00190 strobe_weights_.resize(ctrl_max_concurrent_strobes_->to<mrs_natural>());
00191 for (int n = 0; n < ctrl_max_concurrent_strobes_->to<mrs_natural>(); ++n) {
00192 strobe_weights_[n] = pow(1.0 / (n + 1), (double)ctrl_strobe_weight_alpha_->to<mrs_real>());
00193 }
00194 }
00195
00196 void
00197 AimSAI::ResetInternal() {
00198
00199 active_strobes_.clear();
00200 active_strobes_.resize(channel_count_);
00201 fire_counter_ = frame_period_samples_ - 1;
00202 }
00203
00204
00205
00206
00207
00208
00209 void
00210 AimSAI::findStrobes(realvec& in) {
00211 mrs_natural _inSamples = ctrl_inSamples_->to<mrs_natural>();
00212
00213 strobes_.clear();
00214 strobes_.resize(channel_count_);
00215 for (int o = 0; o < channel_count_; o++) {
00216 strobes_[o].clear();
00217 for (int t = 0; t < _inSamples; t++) {
00218 if (in(o + channel_count_ + channel_count_,t) == 1) {
00219 strobes_[o].push_back(t);
00220 }
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 void
00257 AimSAI::myProcess(realvec& in, realvec& out)
00258 {
00259
00260 mrs_natural _max_concurrent_strobes = ctrl_max_concurrent_strobes_->to<mrs_natural>();
00261 mrs_real _israte = ctrl_israte_->to<mrs_real>();
00262
00263
00264
00265 for (int o = 0; o < channel_count_; ++o) {
00266 centre_frequencies_[o] = in(o + channel_count_);
00267
00268 }
00269
00270 findStrobes(in);
00271
00272
00273 next_strobes_.clear();
00274 next_strobes_.resize(channel_count_, 0);
00275
00276
00277 for (int o = 0; o < channel_count_; ++o) {
00278 active_strobes_[o].ShiftStrobes(ctrl_inSamples_->to<mrs_natural>());
00279 }
00280
00281
00282 for (int t = 0; t < ctrl_inSamples_->to<mrs_natural>(); ++t)
00283 {
00284 double decay_factor = pow(sai_decay_factor_, fire_counter_);
00285
00286
00287 for (int o = 0; o < channel_count_; ++o)
00288 {
00289
00290
00291
00292 StrobeList &active_strobes = active_strobes_[o];
00293 unsigned int next_strobe_index = next_strobes_[o];
00294
00295
00296
00297 if (next_strobe_index < strobes_[o].size()) {
00298
00299
00300
00301
00302 if (t == strobes_[o][next_strobe_index]) {
00303
00304
00305
00306
00307 if (active_strobes.strobe_count() >= _max_concurrent_strobes) {
00308 active_strobes.DeleteFirstStrobe();
00309 }
00310
00311
00312
00313 double weight = 1.0;
00314 if (active_strobes.strobe_count() > 0) {
00315 int last_strobe_time = active_strobes.Strobe(
00316 active_strobes.strobe_count() - 1).time;
00317
00318
00319
00320
00321 weight = (t - last_strobe_time) / _israte
00322 * centre_frequencies_[o] / 10.0;
00323 if (weight > 1.0)
00324 weight = 1.0;
00325 }
00326 active_strobes.AddStrobe(t, weight);
00327 next_strobe_index++;
00328
00329
00330 double total_strobe_weight = 0.0;
00331 for (int si = 0; si < active_strobes.strobe_count(); ++si) {
00332
00333 total_strobe_weight += (active_strobes.Strobe(si).weight
00334 * strobe_weights_[active_strobes.strobe_count() - si - 1]);
00335 }
00336 for (int si = 0; si < active_strobes.strobe_count(); ++si) {
00337
00338 active_strobes.SetWorkingWeight(si,
00339 (active_strobes.Strobe(si).weight
00340 * strobe_weights_[active_strobes.strobe_count() - si - 1])
00341 / total_strobe_weight);
00342 }
00343 }
00344 }
00345
00346
00347 while (active_strobes.strobe_count() > 0) {
00348
00349
00350 if ((t - active_strobes.Strobe(0).time) > max_strobe_delay_idx_) {
00351 active_strobes.DeleteFirstStrobe();
00352 } else {
00353
00354 break;
00355 }
00356 }
00357
00358
00359
00360 for (int si = 0; si < active_strobes.strobe_count(); ++si) {
00361
00362
00363
00364 int delay = t - active_strobes.Strobe(si).time;
00365
00366
00367
00368 if (delay >= min_strobe_delay_idx_ && delay < max_strobe_delay_idx_) {
00369
00370 double sig = in(o, t);
00371
00372
00373
00374 sig *= active_strobes.Strobe(si).working_weight;
00375
00376
00377
00378 sig *= decay_factor;
00379
00380
00381
00382 out(o, delay) = out(o, delay) + sig;
00383 }
00384 }
00385
00386 next_strobes_[o] = next_strobe_index;
00387 }
00388
00389 fire_counter_--;
00390
00391
00392
00393
00394 if (fire_counter_ <= 0) {
00395
00396
00397 double decay = pow(sai_decay_factor_, frame_period_samples_);
00398
00399 for (int o = 0; o < channel_count_; ++o) {
00400
00401 for (int t = 0; t < frame_period_samples_; ++t ) {
00402
00403 out(o, t) = sai_temp_(o,t) + out(o,t) * decay;
00404 }
00405 }
00406
00407
00408 for (int o = 0; o < sai_temp_.getRows(); ++o) {
00409 for (int t = 0; t < sai_temp_.getCols(); ++t) {
00410 sai_temp_(o, t) = 0.0;
00411 }
00412 }
00413 fire_counter_ = frame_period_samples_ - 1;
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424 }