00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "BICchangeDetector.h"
00020 #include "Memory.h"
00021 #include "NumericLib.h"
00022
00023
00024 using std::ostringstream;
00025 using std::cout;
00026 using std::endl;
00027
00028 using namespace Marsyas;
00029
00036 BICchangeDetector::BICchangeDetector(mrs_string name):MarSystem("BICchangeDetector", name)
00037 {
00038 prevDists_ = new Memory("cirMem");
00039 BICTick_ = 0;
00040 nfeats_ = 0;
00041 addControls();
00042 pdists_.create(nrPrevDists_);
00043 }
00044
00051 BICchangeDetector::BICchangeDetector(const BICchangeDetector& a) : MarSystem(a)
00052 {
00053 prevDists_ = new Memory(*(a.prevDists_));
00054
00055 BICTick_ = 0;
00056
00057 nfeats_ = 0;
00058 ctrl_reset_ = getctrl("mrs_bool/reset");
00059 ctrl_alpha1_= getctrl("mrs_real/alpha1");
00060 ctrl_lambda_= getctrl("mrs_real/lambda");
00061 ctrl_prevDists_= getctrl("mrs_natural/prevDists");
00062 ctrl_hopMS_ = getctrl("mrs_natural/hopMillis");
00063 nrPrevDists_ = ctrl_prevDists_->to<mrs_natural>();
00064 pdists_.create(nrPrevDists_);
00065 }
00066
00067 BICchangeDetector::~BICchangeDetector()
00068 {
00069 delete prevDists_;
00070 }
00071
00072 MarSystem*
00073
00079 BICchangeDetector::clone() const
00080 {
00081 return new BICchangeDetector(*this);
00082 }
00083
00094 void
00095 BICchangeDetector::addControls()
00096 {
00097 addctrl("mrs_bool/reset", true, ctrl_reset_);
00098 setctrlState(ctrl_reset_, true);
00099
00100 addctrl("mrs_real/alpha1", 0.6, ctrl_alpha1_);
00101 addctrl("mrs_real/lambda", 0.8, ctrl_lambda_);
00102 addctrl("mrs_natural/prevDists",3,ctrl_prevDists_);
00103 addctrl("mrs_natural/hopMillis",25,ctrl_hopMS_);
00104
00105 dynThres_ = 0.0;
00106 prevDists_->updControl("mrs_natural/inSamples", 1);
00107 prevDists_->updControl("mrs_natural/inObservations", 1);
00108 nrPrevDists_ = getctrl("mrs_natural/prevDists")->to<mrs_natural>();
00109 prevDists_->updControl("mrs_natural/memSize", nrPrevDists_);
00110 }
00111
00134 void
00135 BICchangeDetector::myUpdate(MarControlPtr sender)
00136 {
00137 MarSystem::myUpdate(sender);
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 if(segFrames_ != ctrl_inSamples_->to<mrs_natural>()*2/5 ||
00153 nfeats_ != ctrl_inObservations_->to<mrs_natural>())
00154 {
00155 segFrames_ = ctrl_inSamples_->to<mrs_natural>()*2/5;
00156 segHop_ = ctrl_inSamples_->to<mrs_natural>()*1/5;
00157 hopSeconds_ = 0.001*segHop_*(mrs_real)ctrl_hopMS_->to<mrs_natural>();
00158 nfeats_ = ctrl_inObservations_->to<mrs_natural>();
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 cout << name_ << "BICchangeDetector:" << endl;
00174 cout << " segFrames = " << segFrames_ << endl;
00175 cout << " segHop = " << segHop_ << endl;
00176 cout << " nfeats = " << nfeats_ << endl;
00177
00178 }
00179
00180 if(ctrl_reset_->to<bool>())
00181 {
00182 QGMMmodel_.resetModel();
00183 prevDists_->updControl("mrs_bool/reset", true);
00184 pdists_.setval(0.0);
00185 pIndex_ = 0;
00186 ctrl_reset_->setValue(false, NOUPDATE);
00187 }
00188 }
00189
00190 void
00191 BICchangeDetector::myProcess(realvec& in, realvec& out)
00192 {
00193 ++BICTick_;
00194 mrs_natural o,t;
00195
00196
00197 C1_.create(nfeats_, segFrames_);
00198 C2_.create(nfeats_, segFrames_);
00199 C3_.create(nfeats_, segFrames_);
00200 C4_.create(nfeats_, segFrames_);
00201
00202 for(o=0; o < inObservations_; ++o)
00203 {
00204
00205 for(t=0; t < segFrames_ ; ++t)
00206 {
00207 C1_(o, t) = in(o, t);
00208 C2_(o, t) = in(o, t + segFrames_);
00209 C3_(o, t) = in(o, t + segHop_);
00210 C4_(o, t) = in(o, t + segHop_ + segFrames_);
00211 }
00212
00213
00214 for(t=0; t < inSamples_; ++t)
00215 out(o, t) = in(o, t);
00216 }
00217
00218
00219 realvec tmp;
00220 C1_.covariance(tmp);
00221 C1_ = tmp;
00222 C2_.covariance(tmp);
00223 C2_ = tmp;
00224 C3_.covariance(tmp);
00225 C3_ = tmp;
00226 C4_.covariance(tmp);
00227 C4_ = tmp;
00228
00229
00230 QGMMmodel_.updateModel(C1_, segFrames_);
00231
00232
00233 dist12_ = NumericLib::divergenceShape(C1_, C2_);
00234 dist34_ = NumericLib::divergenceShape(C3_, C4_);
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 dynThres_ = pdists_.mean() * ctrl_alpha1_->to<mrs_real>();
00252
00253
00254
00255
00256
00257
00258 mrs_real distanceLeft = pdists_(pIndex_);
00259 pIndex_ = (pIndex_ + 1) % nrPrevDists_;
00260
00261 mrs_real distanceRight = dist34_;
00262
00263
00264
00265 if(distanceLeft == 0.0)
00266 distanceLeft = dist12_;
00267 if(distanceRight == 0.0)
00268 distanceRight = dist12_;
00269
00270
00271
00272
00273 realvec newDist(1);
00274 newDist(0) = dist12_;
00275 prevDists_->process(newDist, pdists_);
00276
00277
00278
00279
00280 time_t currTime = ((mrs_real)BICTick_)*hopSeconds_;
00281 tm * currTm = gmtime(&currTime);
00282 if(dist12_ > distanceRight && dist12_ > distanceLeft && dist12_ > dynThres_)
00283 {
00284
00285 BICdist_ = QGMMmodel_.BICdistance(C2_, segFrames_, ctrl_lambda_->to<mrs_real>());
00286
00287 mrs_real confidence = 1.0 - dynThres_/dist12_;
00288 cout << name_ << ": Potential change, with confidence " << confidence
00289 << " at " << currTm->tm_hour << "h::"
00290 << currTm->tm_min << "m::"
00291 << currTm->tm_sec << "s";
00292
00293
00294
00295 if(BICdist_ > 0.0)
00296 {
00297
00298
00299
00300
00301 QGMMmodel_.resetModel();
00302
00303
00304
00305
00306
00307
00308
00309 cout << " confirmed!";
00310 }
00311 else
00312 {
00313 cout << " UNCONFIRMED.";
00314
00315
00316 }
00317 cout << endl;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 }