00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "BeatAgent.h"
00020 #include <string.h>
00021 #include "common.h"
00022
00023 using namespace std;
00024 using namespace Marsyas;
00025
00026 #define NONE 0.0
00027 #define BEAT 1.0
00028 #define EVAL 2.0
00029
00030 #define INNER 3.0
00031 #define OUTTER 4.0
00032
00033 BeatAgent::BeatAgent(mrs_string name):MarSystem("BeatAgent", name)
00034 {
00035 addControls();
00036 beatCount_ = 0;
00037 score_ = 0;
00038 curBeatPointValue_ = 0;
00039 myIndex_ = -1;
00040 fraction_ = 0.0;
00041 }
00042
00043 BeatAgent::BeatAgent(const BeatAgent& a) : MarSystem(a)
00044 {
00045
00046
00047
00048 ctrl_identity_ = getctrl("mrs_string/identity");
00049 ctrl_timming_ = getctrl("mrs_natural/timming");
00050 ctrl_agentControl_ = getctrl("mrs_realvec/agentControl");
00051 ctrl_scoreFunc_ = getctrl("mrs_string/scoreFunc");
00052 ctrl_lftOutterMargin_ = getctrl("mrs_real/lftOutterMargin");
00053 ctrl_rgtOutterMargin_ = getctrl("mrs_real/rgtOutterMargin");
00054 ctrl_innerMargin_ = getctrl("mrs_real/innerMargin");
00055 ctrl_maxPeriod_ = getctrl("mrs_natural/maxPeriod");
00056 ctrl_minPeriod_ = getctrl("mrs_natural/minPeriod");
00057
00058 beatCount_ = a.beatCount_;
00059 lastBeatPoint_ = a.lastBeatPoint_;
00060 score_ = a.score_;
00061 curBeatPointValue_ = a.curBeatPointValue_;
00062 myIndex_ = a.myIndex_;
00063 }
00064
00065 BeatAgent::~BeatAgent()
00066 {
00067 }
00068
00069 MarSystem*
00070 BeatAgent::clone() const
00071 {
00072 return new BeatAgent(*this);
00073 }
00074
00075 void
00076 BeatAgent::addControls()
00077 {
00078
00079 addctrl("mrs_string/identity", "AgentX", ctrl_identity_);
00080 addctrl("mrs_natural/timming", 0, ctrl_timming_);
00081 addctrl("mrs_realvec/agentControl", realvec(), ctrl_agentControl_);
00082 addctrl("mrs_string/scoreFunc", "regular", ctrl_scoreFunc_);
00083 setctrlState("mrs_string/scoreFunc", true);
00084 addctrl("mrs_real/lftOutterMargin", 0.2, ctrl_lftOutterMargin_);
00085 setctrlState("mrs_real/lftOutterMargin", true);
00086 addctrl("mrs_real/rgtOutterMargin", 0.4, ctrl_rgtOutterMargin_);
00087 setctrlState("mrs_real/rgtOutterMargin", true);
00088 addctrl("mrs_real/innerMargin", 3.0, ctrl_innerMargin_);
00089 setctrlState("mrs_real/innerMargin", true);
00090 addctrl("mrs_natural/maxPeriod", -1, ctrl_maxPeriod_);
00091 setctrlState("mrs_natural/maxPeriod", true);
00092 addctrl("mrs_natural/minPeriod", -1, ctrl_minPeriod_);
00093 setctrlState("mrs_natural/minPeriod", true);
00094 }
00095
00096 void
00097 BeatAgent::myUpdate(MarControlPtr sender)
00098 {
00099 MRSDIAG("BeatAgent.cpp - BeatAgent:myUpdate");
00100
00101 ctrl_onSamples_->setValue(6, NOUPDATE);
00102 ctrl_onObservations_->setValue(1, NOUPDATE);
00103 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00104
00105
00106 lastBeatPoint_ = inSamples_-1;
00107
00108 myIndex_ = getChildIndex();
00109 if(myIndex_ == -1)
00110 MRSWARN("Agent Index Not Found!");
00111
00112 scoreFunc_ = ctrl_scoreFunc_->to<mrs_string>();
00113
00114 lftOutterMargin_ = ctrl_lftOutterMargin_->to<mrs_real>();
00115 rgtOutterMargin_ = ctrl_rgtOutterMargin_->to<mrs_real>();
00116 innerMargin_ = ctrl_innerMargin_->to<mrs_real>();
00117 maxPeriod_ = ctrl_maxPeriod_->to<mrs_natural>();
00118 minPeriod_ = ctrl_minPeriod_->to<mrs_natural>();
00119 }
00120
00121
00122
00123 mrs_real
00124 BeatAgent::calcDScoreCorrSquare(realvec& in)
00125 {
00126 mrs_real dScore = 0.0;
00127
00128
00129 for(mrs_natural t = lastBeatPoint_ - outterWinLft_; t < lastBeatPoint_ - innerWin_; t++)
00130 {
00131 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00132
00133
00134 dScore += -1 * pow((fraction_),2) * in(t);
00135 }
00136
00137
00138 for(mrs_natural t = lastBeatPoint_ - innerWin_; t <= lastBeatPoint_ + innerWin_; t++)
00139 {
00140 fraction_ = (mrs_real) abs(error_) / (((outterWinRgt_+outterWinLft_)/2)+0.5);
00141
00142
00143 dScore += pow((1 - fraction_),2) * in(t);
00144
00145 }
00146
00147
00148 for(mrs_natural t = (lastBeatPoint_ + innerWin_)+1; t <= lastBeatPoint_ + outterWinRgt_; t++)
00149 {
00150 fraction_ = (mrs_real) abs(error_) / outterWinLft_;
00151
00152
00153 dScore += -1 * pow((fraction_),2) * in(t);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 return dScore * (period_ / maxPeriod_);
00163 }
00164
00165 mrs_real
00166 BeatAgent::calcDScoreCorr(realvec& in, mrs_natural maxInd)
00167 {
00168 mrs_real dScore = 0.0;
00169
00170
00171 for(mrs_natural t = lastBeatPoint_ - outterWinLft_; t < lastBeatPoint_ - innerWin_; t++)
00172 {
00173 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00174
00175 dScore += (-1 * fraction_) * in(t);
00176 }
00177
00178
00179 for(mrs_natural t = lastBeatPoint_ - innerWin_; t <= lastBeatPoint_ + innerWin_; t++)
00180 {
00181 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00182
00183 dScore += (1 - fraction_) * in(t);
00184 }
00185
00186
00187 for(mrs_natural t = (lastBeatPoint_ + innerWin_)+1; t <= lastBeatPoint_ + outterWinRgt_; t++)
00188 {
00189 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00190
00191 dScore += (-1 * fraction_) * in(t);
00192 }
00193
00194
00195
00196
00197 return dScore * (period_ / maxPeriod_);
00198
00199 }
00200
00201 mrs_natural
00202 BeatAgent::getChildIndex()
00203 {
00204
00205 MarSystem* parent = this->getParent();
00206 myIndex_ = -1;
00207 if(parent)
00208 {
00209 vector<MarSystem*> siblings = parent->getChildren();
00210 for(mrs_natural i = 0; i < siblings.size(); i++)
00211 {
00212 if(this == siblings[i])
00213 {
00214 myIndex_ = i;
00215 break;
00216 }
00217 }
00218 }
00219 return myIndex_;
00220 }
00221
00222 void
00223 BeatAgent::fillOutput(realvec& out, mrs_real flag, mrs_real period, mrs_real curBeat,
00224 mrs_real tolerance, mrs_real error, mrs_real score)
00225 {
00226 out(0) = flag;
00227 out(1) = period;
00228 out(2) = curBeat;
00229 out(3) = tolerance;
00230 out(4) = error;
00231 out(5) = score;
00232 }
00233
00234 void
00235 BeatAgent::myProcess(realvec& in, realvec& out)
00236 {
00237
00238 agentControl_ = ctrl_agentControl_->to<mrs_realvec>();
00239
00240
00241 timeElapsed_ = (mrs_natural) agentControl_(myIndex_, 3);
00242
00243
00244
00245
00246 fillOutput(out, NONE, 0.0, 0.0, 0.0, 0.0, 0.0);
00247
00248 identity_ = ctrl_identity_->to<mrs_string>();
00249
00250 isNewOrUpdated_ = (mrs_bool) agentControl_(myIndex_, 0);
00251 period_ = (mrs_natural) agentControl_(myIndex_, 1);
00252 phase_ = (mrs_natural) agentControl_(myIndex_, 2);
00253 periodFraction_ = ((mrs_real)period_ / (mrs_real)maxPeriod_);
00254
00255 outterWinLft_ = (mrs_natural) ceil(period_ * lftOutterMargin_);
00256 outterWinRgt_ = (mrs_natural) ceil(period_ * rgtOutterMargin_);
00257 innerWin_ = (mrs_natural) innerMargin_;
00258
00259
00260 mrs_natural curBeatPoint = inSamples_-1;
00261
00262 mrs_real max = 0.0;
00263 mrs_natural max_i = 0;
00264
00265
00266 if(isNewOrUpdated_)
00267 curBeat_ = phase_;
00268
00269 else
00270 curBeat_ = prevBeat_ + period_;
00271
00272
00273
00274
00275 if(timeElapsed_ == curBeat_)
00276 {
00277
00278
00279
00280 fillOutput(out, BEAT, -1.0, -1.0, -1.0, -1.0, -1.0);
00281
00282 curBeatPointValue_ = in(curBeatPoint);
00283
00284
00285
00286
00287
00288
00289 lastBeatPoint_ = curBeatPoint - outterWinRgt_;
00290
00291 beatCount_++;
00292
00293 return;
00294 }
00295
00296 mrs_natural evalPoint = curBeat_ + outterWinRgt_;
00297
00298 if(timeElapsed_ == evalPoint)
00299 {
00300
00301 max_i = lastBeatPoint_;
00302
00303 for(mrs_natural t = lastBeatPoint_ - outterWinLft_; t <= lastBeatPoint_ + outterWinRgt_; t++)
00304 {
00305
00306 if(max < in(t))
00307 {
00308 max = in(t);
00309 max_i = t;
00310 }
00311 }
00312
00313
00314 error_ = max_i - lastBeatPoint_;
00315
00316
00317
00318
00319
00320
00321 if(strcmp(scoreFunc_.c_str(), "squareCorr") == 0)
00322 score_ = calcDScoreCorrSquare(in);
00323
00324 else if(strcmp(scoreFunc_.c_str(), "correlation") == 0)
00325 score_ = calcDScoreCorr(in, max_i);
00326
00327
00328
00329 if(max_i >= lastBeatPoint_ - innerWin_ && max_i <= lastBeatPoint_)
00330 {
00331 if(strcmp(scoreFunc_.c_str(), "regular") == 0)
00332 {
00333 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00334
00335
00336 score_ = (1 - fraction_) * max * periodFraction_;
00337
00338
00339
00340 }
00341
00342 MRSDIAG("BeatAgent::myProcess() - Beat Inside innerWindow!");
00343
00344
00345
00346
00347 fillOutput(out, EVAL, period_, curBeat_, INNER, error_, score_);
00348 }
00349 else if(max_i > lastBeatPoint_ && max_i <= lastBeatPoint_ + innerWin_)
00350 {
00351 if(strcmp(scoreFunc_.c_str(), "regular") == 0)
00352 {
00353 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00354
00355
00356 score_ = (1 - fraction_) * max * periodFraction_;
00357
00358
00359
00360 }
00361
00362 MRSDIAG("BeatAgent::myProcess() - Beat Inside innerWindow!");
00363
00364
00365
00366
00367 fillOutput(out, EVAL, period_, curBeat_, INNER, error_, score_);
00368 }
00369
00370
00371 else
00372 {
00373 if((max_i >= lastBeatPoint_ - outterWinLft_) && (max_i < lastBeatPoint_ - innerWin_))
00374 {
00375 if(strcmp(scoreFunc_.c_str(), "regular") == 0)
00376 {
00377 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00378
00379
00380 score_ = -1 * fraction_ * max * periodFraction_;
00381
00382
00383
00384 }
00385 }
00386 if((max_i > lastBeatPoint_ + innerWin_) && (max_i <= lastBeatPoint_ + outterWinRgt_))
00387 {
00388 if(strcmp(scoreFunc_.c_str(), "regular") == 0)
00389 {
00390 fraction_ = (mrs_real) abs(error_) / outterWinRgt_;
00391
00392
00393 score_ = -1 * fraction_ * max * periodFraction_;
00394
00395
00396
00397 }
00398 }
00399
00400
00401
00402
00403 MRSDIAG("BeatAgent::myProcess() - Beat Inside OutterWindow but outside innerWindow!");
00404
00405 fillOutput(out, EVAL, period_, curBeat_, OUTTER, error_, score_);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 prevBeat_ = curBeat_;
00422
00423
00424 agentControl_(myIndex_, 0) = 0.0;
00425 updControl(ctrl_agentControl_, agentControl_);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 }