00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "BeatTimesSink.h"
00020 #include <fstream>
00021 #include <string.h>
00022
00023 using namespace std;
00024 using namespace Marsyas;
00025
00026 char *szServer = "localhost";
00027
00028 BeatTimesSink::BeatTimesSink(mrs_string name):MarSystem("BeatTimesSink", name)
00029 {
00030 addControls();
00031 ibiBPM_ = 0.0;
00032 ibiBPMSum_ = 0.0;
00033 beatCount_ = 0;
00034 timeElapsed_ = 0;
00035 inc_ = 0;
00036 nonCausal_ = true;
00037 lastIbi_ = 0.0;
00038 initialOut_ = true;
00039 initialOut2_ = true;
00040 initialOut3_ = true;
00041
00042 }
00043
00044 BeatTimesSink::BeatTimesSink(const BeatTimesSink& a) : MarSystem(a)
00045 {
00046
00047
00048
00049 ctrl_hopSize_ = getctrl("mrs_natural/hopSize");
00050 ctrl_winSize_ = getctrl("mrs_natural/winSize");
00051 ctrl_srcFs_ = getctrl("mrs_real/srcFs");
00052 ctrl_destFileName_ = getctrl("mrs_string/destFileName");
00053 ctrl_mode_ = getctrl("mrs_string/mode");
00054 ctrl_tickCount_ = getctrl("mrs_natural/tickCount");
00055 ctrl_tempo_ = getctrl("mrs_real/tempo");
00056 ctrl_adjustment_ = getctrl("mrs_natural/adjustment");
00057 ctrl_bestFinalAgentHistory_= getctrl("mrs_realvec/bestFinalAgentHistory");
00058 ctrl_soundFileSize_= getctrl("mrs_natural/soundFileSize");
00059 ctrl_nonCausal_ = getctrl("mrs_bool/nonCausal");
00060 ctrl_socketsPort_ = getctrl("mrs_natural/socketsPort");
00061
00062 ibiBPM_ = a.ibiBPM_;
00063 beatCount_ = a.beatCount_;
00064 ibiBPMSum_ = a.ibiBPMSum_;
00065 inc_ = a.inc_;
00066 ibiBPMVec_ = a.ibiBPMVec_;
00067 initialOut_ = a.initialOut_;
00068 initialOut2_ = a.initialOut2_;
00069 initialOut3_ = a.initialOut3_;
00070
00071
00072
00073
00074 }
00075
00076 BeatTimesSink::~BeatTimesSink()
00077 {
00078 }
00079
00080 MarSystem*
00081 BeatTimesSink::clone() const
00082 {
00083 return new BeatTimesSink(*this);
00084 }
00085
00086 void
00087 BeatTimesSink::addControls()
00088 {
00089
00090 addctrl("mrs_natural/tickCount", 0, ctrl_tickCount_);
00091 addctrl("mrs_natural/hopSize", -1, ctrl_hopSize_);
00092 setctrlState("mrs_natural/hopSize", true);
00093 addctrl("mrs_natural/winSize", -1, ctrl_winSize_);
00094 setctrlState("mrs_natural/winSize", true);
00095 addctrl("mrs_real/srcFs", -1.0, ctrl_srcFs_);
00096 setctrlState("mrs_real/srcFs", true);
00097 addctrl("mrs_string/destFileName", "output", ctrl_destFileName_);
00098 addctrl("mrs_string/mode", "beats+tempo", ctrl_destFileName_);
00099 setctrlState("mrs_string/mode", true);
00100 addctrl("mrs_real/tempo", 80.0, ctrl_tempo_);
00101 addctrl("mrs_natural/adjustment", 0, ctrl_adjustment_);
00102 setctrlState("mrs_natural/adjustment", true);
00103 addctrl("mrs_realvec/bestFinalAgentHistory", realvec(), ctrl_bestFinalAgentHistory_);
00104 setctrlState("mrs_realvec/bestFinalAgentHistory", true);
00105 addctrl("mrs_natural/soundFileSize", 0, ctrl_soundFileSize_);
00106 setctrlState("mrs_natural/soundFileSize", true);
00107 addctrl("mrs_bool/nonCausal", false, ctrl_nonCausal_);
00108 setctrlState("mrs_bool/nonCausal", true);
00109 addctrl("mrs_natural/socketsPort", -1, ctrl_socketsPort_);
00110 setctrlState("mrs_natural/socketsPort", true);
00111 }
00112
00113 void
00114 BeatTimesSink::myUpdate(MarControlPtr sender)
00115 {
00116 MRSDIAG("BeatTimesSink.cpp - BeatTimesSink:myUpdate");
00117 MarSystem::myUpdate(sender);
00118
00119 hopSize_ = ctrl_hopSize_->to<mrs_natural>();
00120 winSize_ = ctrl_winSize_->to<mrs_natural>();
00121 srcFs_ = ctrl_srcFs_->to<mrs_real>();
00122
00123 adjustment_ = (mrs_real) ctrl_adjustment_->to<mrs_natural>();
00124
00125 mode_ = ctrl_mode_->to<mrs_string>();
00126
00127 bestFinalAgentHistory_ = ctrl_bestFinalAgentHistory_->to<mrs_realvec>();
00128 soundFileSize_ = ctrl_soundFileSize_->to<mrs_natural>();
00129 nonCausal_ = ctrl_nonCausal_->to<mrs_bool>();
00130 socketsPort_ = ctrl_socketsPort_->to<mrs_natural>();
00131 }
00132
00133 mrs_natural
00134 BeatTimesSink::refreshSocket()
00135 {
00136 #pragma comment(lib, "Ws2_32.lib") //include Ws2_32.lib
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 return 1;
00165 }
00166
00167 mrs_realvec
00168 BeatTimesSink::addMedianVector(mrs_real ibiBPM)
00169 {
00170 mrs_bool bigger = false;
00171 mrs_realvec tmp(beatCount_);
00172
00173
00174 if(beatCount_ >= ibiBPMVec_.getSize())
00175 ibiBPMVec_.stretch(beatCount_);
00176
00177 for(mrs_natural j = 0; j < beatCount_-1; j++)
00178 {
00179
00180 tmp(j) = ibiBPMVec_(j);
00181 }
00182 for(mrs_natural i = beatCount_-2; i >=0 ; i--)
00183 {
00184 if(ibiBPM > ibiBPMVec_(i))
00185 {
00186 ibiBPMVec_(i+1) = ibiBPM;
00187 for(mrs_natural z = i+1; z < beatCount_-1; z++)
00188 ibiBPMVec_(z+1) = tmp(z);
00189
00190
00191 bigger = true;
00192 break;
00193 }
00194 }
00195 if(!bigger)
00196 {
00197 ibiBPMVec_(0) = ibiBPM;
00198 for(mrs_natural z = 0; z < beatCount_-1; z++)
00199 ibiBPMVec_(z+1) = tmp(z);
00200
00201 }
00202
00203
00204
00205
00206 return ibiBPMVec_;
00207 }
00208
00209 void
00210 BeatTimesSink::myProcess(realvec& in, realvec& out)
00211 {
00212
00213 timeElapsed_ = ctrl_tickCount_->to<mrs_natural>()-1;
00214
00215
00216
00217
00218 out = in;
00219
00220 if(!nonCausal_)
00221 {
00222
00223 if(in(0,0) == 1.0)
00224 {
00225
00226 if(beatCount_ >= inc_)
00227 {
00228
00229 srcFs_ = ctrl_srcFs_->to<mrs_real>();
00230 beatTime_ = ((timeElapsed_ * hopSize_) - adjustment_) / srcFs_;
00231
00232
00233
00234
00235 if(!initialOut_ || !initialOut2_ || !initialOut3_)
00236 ibiBPM_ = (60.0 / (beatTime_ - lastBeatTime_));
00237
00238
00239
00240 fstream outStream;
00241 fstream outStream2;
00242 fstream outStream3;
00243
00244 if((strcmp(mode_.c_str(), "beatTimes") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo") == 0)
00245 || (strcmp(mode_.c_str(), "beats+medianTempo") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00246 {
00247 ostringstream oss;
00248
00249
00250
00251 if(initialOut_)
00252 {
00253 oss << ctrl_destFileName_->to<mrs_string>() << ".txt";
00254 outStream.open(oss.str().c_str(), ios::out|ios::trunc);
00255 outStream << beatTime_ << endl;
00256 outStream.close();
00257 initialOut_ = false;
00258 }
00259
00260
00261 else
00262 {
00263 oss << ctrl_destFileName_->to<mrs_string>() << ".txt";
00264 outStream.open(oss.str().c_str(), ios::out|ios::app);
00265
00266 outStream << beatTime_ << " " << ibiBPM_ << endl;
00267
00268 }
00269 }
00270
00271 if((strcmp(mode_.c_str(), "meanTempo") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo") == 0)
00272 || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00273 {
00274 ostringstream oss2;
00275 if(initialOut2_)
00276 {
00277 oss2 << ctrl_destFileName_->to<mrs_string>() << "_meanTempo.txt";
00278
00279 outStream2.open(oss2.str().c_str(), ios::out|ios::trunc);
00280 outStream2.close();
00281 initialOut2_ = false;
00282 }
00283
00284 if(beatCount_ > inc_)
00285 {
00286 ibiBPMSum_ += ibiBPM_;
00287 mrs_natural output = (mrs_natural) ((ibiBPMSum_ / (beatCount_-inc_)) + 0.5);
00288
00289 oss2 << ctrl_destFileName_->to<mrs_string>() << "_meanTempo.txt";
00290 outStream2.open(oss2.str().c_str());
00291 outStream2 << output << endl;
00292 outStream2.close();
00293 }
00294 }
00295
00296 if((strcmp(mode_.c_str(), "medianTempo") == 0) || (strcmp(mode_.c_str(), "beats+medianTempo") == 0)
00297 || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00298 {
00299 ostringstream oss3;
00300 if(initialOut3_)
00301 {
00302 oss3 << ctrl_destFileName_->to<mrs_string>() << "_medianTempo.txt";
00303 outStream3.open(oss3.str().c_str(), ios::out|ios::trunc);
00304 outStream3.close();
00305 initialOut3_ = false;
00306 }
00307
00308 if(beatCount_ > inc_)
00309 {
00310 addMedianVector(ibiBPM_);
00311
00312 mrs_natural output;
00313 output = (mrs_natural) (ibiBPMVec_((mrs_natural)(beatCount_ / 2.0)) + 0.5);
00314 tempo_ = output;
00315 ctrl_tempo_->setValue(tempo_, NOUPDATE);
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 oss3 << ctrl_destFileName_->to<mrs_string>() << "_medianTempo.txt";
00334 outStream3.open(oss3.str().c_str());
00335 outStream3 << output << endl;
00336 outStream3.close();
00337
00338
00339 }
00340
00341 else if(beatCount_ == 2)
00342 {
00343 oss3 << ctrl_destFileName_->to<mrs_string>() << "_medianTempo.txt";
00344 outStream.open(oss3.str().c_str());
00345 outStream << (mrs_natural) (ibiBPM_ + 0.5);
00346 outStream.close();
00347 tempo_ = ibiBPM_;
00348 ctrl_tempo_->setValue(tempo_, NOUPDATE);
00349 }
00350 }
00351
00352
00353
00354 lastBeatTime_ = beatTime_;
00355 }
00356 beatCount_ ++;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 }
00379 if(nonCausal_)
00380 {
00381 if(timeElapsed_ == soundFileSize_-1)
00382 {
00383
00384 if(bestFinalAgentHistory_(0) >= 0.0)
00385 {
00386
00387 for(mrs_natural i = 0; i < beatCount_; i++)
00388 ibiBPMVec_(i) = 0.0;
00389 beatCount_ = 0;
00390 ibiBPMSum_ = 0.0;
00391
00392
00393 beatTime_ = ((bestFinalAgentHistory_(0) * hopSize_) - adjustment_) / srcFs_;
00394 lastBeatTime_ = beatTime_;
00395 beatTimeTmp_ = beatTime_;
00396 beatCount_++;
00397
00398 fstream outStream;
00399 ostringstream oss;
00400 if((strcmp(mode_.c_str(), "beatTimes") == 0) || (strcmp(mode_.c_str(), "beats+medianTempo") == 0)
00401 || (strcmp(mode_.c_str(), "beats+meanTempo") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00402 {
00403 oss << ctrl_destFileName_->to<mrs_string>() << ".txt";
00404 outStream.open(oss.str().c_str(), ios::out|ios::trunc);
00405 outStream << beatTime_ << endl;
00406 }
00407
00408
00409 for(int i = 1; i < bestFinalAgentHistory_.getCols(); i++)
00410 {
00411 beatTime_ = ((bestFinalAgentHistory_(i) * hopSize_) - adjustment_) / srcFs_;
00412
00413 mrs_real ibi = (beatTime_ - lastBeatTime_);
00414
00415
00416
00417 mrs_real nextIbi = 0;
00418 mrs_real nextBeatTime = 0;
00419
00420
00421 nextBeatTime = ((bestFinalAgentHistory_(i+1) * hopSize_) - adjustment_) / srcFs_;
00422 nextIbi = (nextBeatTime - beatTimeTmp_);
00423
00424
00425
00426
00427
00428
00429
00430 addMedianVector(ibiBPM_);
00431
00432
00433
00434
00435
00436
00437
00438 ibiBPM_ = (60.0 / ibi);
00439
00440 if((strcmp(mode_.c_str(), "beatTimes") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo") == 0)
00441 || (strcmp(mode_.c_str(), "beats+medianTempo") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00442 {
00443 outStream << beatTime_ << " " << ibiBPM_ << endl;
00444 }
00445
00446 addMedianVector(ibiBPM_);
00447 ibiBPMSum_ += ibiBPM_;
00448 lastBeatTime_ = beatTime_;
00449 beatTimeTmp_ = nextBeatTime;
00450 beatCount_ ++;
00451
00452 lastIbi_ = ibi;
00453 }
00454
00455 if((strcmp(mode_.c_str(), "meanTempo") == 0) || (strcmp(mode_.c_str(), "beats+meanTempo") == 0)
00456 || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00457 {
00458 ostringstream oss2;
00459 fstream outStream2;
00460 oss2 << ctrl_destFileName_->to<mrs_string>() << "_meanTempo.txt";
00461 outStream2.open(oss2.str().c_str(), ios::out|ios::trunc);
00462 outStream2 << (mrs_natural) ((ibiBPMSum_/beatCount_) + 0.5) << endl;
00463 outStream2.close();
00464 }
00465
00466 if((strcmp(mode_.c_str(), "medianTempo") == 0) || (strcmp(mode_.c_str(), "beats+medianTempo") == 0)
00467 || (strcmp(mode_.c_str(), "beats+meanTempo+medianTempo") == 0))
00468 {
00469 mrs_natural output;
00470 output = (mrs_natural) (ibiBPMVec_((mrs_natural)(beatCount_ / 2.0)) + 0.5);
00471 tempo_ = output;
00472 ctrl_tempo_->setValue(tempo_, NOUPDATE);
00473
00474 ostringstream oss3;
00475 fstream outStream3;
00476 oss3 << ctrl_destFileName_->to<mrs_string>() << "_medianTempo.txt";
00477 outStream3.open(oss3.str().c_str(), ios::out|ios::trunc);
00478 outStream3 << output << endl;
00479 outStream3.close();
00480
00481
00482
00483 }
00484 }
00485 }
00486 }
00487
00488 }
00489
00490
00491
00492
00493
00494
00495
00496