annotate newOFsrc/testApp.cpp @ 12:e148d1534733 tip

adding new max player
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 09 Mar 2012 20:42:34 +0000
parents 23ff520d28ff
children
rev   line source
andrew@2 1 #include "testApp.h"
andrew@2 2
andrew@2 3
andrew@2 4 //--------------------------------------------------------------
andrew@2 5 //relooking at this problem
andrew@2 6 //bayesianTempo7 - have had working well with Bayesian8NEW maxmsp set
andrew@2 7
andrew@2 8 //updated in bayesian8
andrew@2 9 //integrate so that maxPhase and tempo are the integrated result across the pdf
andrew@2 10 //rather tahn the maximum index - tends to reflect the actuial distribution better
andrew@2 11 //and is the "correct" bayesian method
andrew@2 12
andrew@2 13 //added [ and ] tpo change the alignment when rescue is needed
andrew@2 14
andrew@2 15 //in Bayesian9 (BayesianTest8NEW)
andrew@2 16 //added noise in phase process
andrew@2 17 //started probability distribution for observed beat events
andrew@2 18
andrew@2 19 //in bayesian 11
andrew@2 20 //get s.d. of posterior
andrew@2 21 //this is set to be used as the s.d. of the likelihood
andrew@2 22
andrew@2 23
andrew@2 24 //Initialiser : the algorithm has an initialisation stage with flat prior that detects liekly tempo
andrew@2 25
andrew@2 26
andrew@2 27
andrew@2 28 //BAYESIAN DISTRIBUTION SET by class BayesianArray
andrew@2 29 //SETUP - initialises array
andrew@2 30 //UPDATE - decay the distribution with noise
andrew@2 31 //this should be done using tempo and noise
andrew@2 32 //DRAW - Draw current distributions and also the maximum
andrew@2 33
andrew@2 34 //Runs with bayesian11NEW
andrew@2 35 //and B-KeeperOldBayesianTestNew in Live
andrew@2 36 //Needs - categorisation of beats and tempo
andrew@2 37 //can we use our distribution to filter the input or is that cheating?
andrew@2 38
andrew@2 39 //INtroduce lock scheme for tempo - we know where the beat fell, so can calculate the appropriate tempo interval
andrew@2 40
andrew@2 41 void testApp::setup(){
andrew@9 42
andrew@10 43 outputFile.open("../../../data/baydrumTest.txt");
andrew@9 44
andrew@2 45 // listen on the given port
andrew@2 46 cout << "listening for osc messages on port " << PORT << "\n";
andrew@2 47 receiver.setup( PORT );
andrew@2 48
andrew@2 49 // sender.setup( HOST, OUTPORT );
andrew@2 50 ofSetCircleResolution(50);
andrew@2 51 ofBackground(255,255,255);
andrew@2 52 bSmooth = false;
andrew@2 53 msg_string = "setup";
andrew@2 54
andrew@2 55 ofSetWindowTitle("Bayesian Test");
andrew@2 56
andrew@2 57 ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps.
andrew@2 58
andrew@2 59 KLdiv = 0;
andrew@3 60 entropy = 0;
andrew@2 61
andrew@2 62 hidePriorMode = false;
andrew@2 63
andrew@2 64 printInterval = true;
andrew@2 65 drawData = false;
andrew@2 66
andrew@2 67 screenToDraw = 0;
andrew@2 68
andrew@2 69 ofSetLineWidth(2);
andrew@2 70 ofEnableSmoothing();
andrew@2 71
andrew@2 72
andrew@2 73 bSnapshot = false;
andrew@2 74 snapCounter = 0;
andrew@2 75
andrew@2 76 drumTracker.paused = false;
andrew@2 77
andrew@2 78 // setDistributionOnStartTempo = true;
andrew@2 79
andrew@2 80 resetParameters();
andrew@2 81
andrew@10 82 arrayToMsecScaleFactor = (drumTracker.tempoMaximum - drumTracker.tempoMinimum)/ drumTracker.arraySize;//turns array into ms
andrew@2 83 tempoWindowMinimum = 100;
andrew@2 84 tempoWindowMaximum = 150;
andrew@2 85 tempoWindowWidth = 50;
andrew@2 86 }
andrew@2 87
andrew@2 88
andrew@2 89 void testApp::resetParameters(){
andrew@2 90
andrew@2 91 }
andrew@2 92
andrew@2 93 //--------------------------------------------------------------
andrew@2 94 void testApp::update(){
andrew@2 95
andrew@2 96
andrew@2 97 updateOSCmessages();
andrew@2 98
andrew@2 99 //update tempo window range - this for viewing tempo closeup
andrew@2 100 while (tempoWindowMinimum + tempoWindowWidth/4 > drumTracker.tempoDistribution.integratedEstimate)
andrew@2 101 tempoWindowMinimum -= tempoWindowWidth/4;
andrew@2 102
andrew@2 103 while (tempoWindowMinimum + 3*tempoWindowWidth/4 < drumTracker.tempoDistribution.integratedEstimate)
andrew@2 104 tempoWindowMinimum += tempoWindowWidth/4;
andrew@2 105
andrew@2 106 tempoWindowMaximum = tempoWindowMinimum + tempoWindowWidth;
andrew@2 107
andrew@2 108 drumTracker.decayDistributions();
andrew@2 109
andrew@2 110 }
andrew@2 111
andrew@2 112
andrew@2 113 void testApp::updateOSCmessages(){
andrew@2 114
andrew@2 115
andrew@2 116 // check for waiting messages
andrew@2 117 while( receiver.hasWaitingMessages() )
andrew@2 118 {
andrew@2 119 ofxOscMessage m;
andrew@2 120 receiver.getNextMessage( &m );
andrew@2 121 string newAddress = m.getAddress();
andrew@2 122
andrew@2 123 if ( m.getAddress() == "/Reset" ){
andrew@2 124 printf("baysian reset\n");
andrew@2 125 drumTracker.resetParameters();
andrew@9 126 outputFile.close();
andrew@2 127 }
andrew@2 128
andrew@2 129
andrew@2 130 if ( m.getAddress() == "/beatError" ){
andrew@10 131 newBeatInformation(m);//this is the main beat error routine (input)
andrew@4 132 }//end if new error
andrew@2 133
andrew@2 134
andrew@2 135
andrew@2 136 if ( m.getAddress() == "/tatum" ){
andrew@2 137 drumTracker.beatTimes.tatum = m.getArgAsFloat(0);
andrew@2 138 printf("got tatum as %f\n", m.getArgAsFloat(0));
andrew@2 139 }
andrew@2 140
andrew@2 141 if ( m.getAddress() == "/startTatum" ){
andrew@2 142 drumTracker.startTatum(m.getArgAsFloat(0));
andrew@2 143 printf("START TATUM %f\n", m.getArgAsFloat(0));
andrew@2 144 //then change so tempo distribution is correct....
andrew@2 145 }//end start tatum
andrew@2 146
andrew@2 147
andrew@2 148 if ( m.getAddress() == "/uniformTempo" ){
andrew@2 149 drumTracker.setUniformTempo();
andrew@2 150
andrew@2 151 }
andrew@2 152
andrew@2 153
andrew@2 154 if ( m.getAddress() == "/uniformPhase" ){
andrew@2 155 drumTracker.setUniformPhase();
andrew@2 156
andrew@2 157 }
andrew@2 158
andrew@2 159
andrew@2 160 if ( m.getAddress() == "/setBeatNow" ){
andrew@2 161
andrew@2 162 double beatTime = m.getArgAsFloat(0);
andrew@2 163 drumTracker.setBeatNow(beatTime);
andrew@2 164 //printf("SET BEAT NOW %f\n", beatTime);
andrew@2 165 }
andrew@2 166
andrew@2 167
andrew@2 168 if ( m.getAddress() == "/clickindex" ){
andrew@2 169
andrew@2 170 int clickIndex = m.getArgAsInt32(0);
andrew@2 171 float clickTime = m.getArgAsFloat(1);
andrew@2 172 drumTracker.setNewClickIndex(clickIndex, clickTime);
andrew@2 173 }
andrew@2 174
andrew@2 175
andrew@2 176 if ( m.getAddress() == "/newBeat" ){
andrew@2 177 int beatIndex = m.getArgAsInt32(0);
andrew@2 178 drumTracker.newBeat(beatIndex);
andrew@2 179 }
andrew@2 180
andrew@2 181
andrew@2 182 if ( m.getAddress() == "/beatCorrection" )
andrew@2 183 {
andrew@2 184 float beatCorrValue = m.getArgAsFloat(0);
andrew@2 185 drumTracker.doBeatCorrection(beatCorrValue);
andrew@2 186
andrew@2 187 }//end correction by
andrew@2 188
andrew@2 189
andrew@2 190 if ( m.getAddress() == "/BayesianNoise" ){
andrew@2 191 drumTracker.beatDistribution.likelihoodNoise = m.getArgAsFloat(0);;
andrew@2 192 printf("bayesian noise set to %f\n", drumTracker.beatDistribution.likelihoodNoise);
andrew@2 193 // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev);
andrew@2 194 }
andrew@2 195
andrew@2 196 if ( m.getAddress() == "/BayesianStdDev" ){
andrew@10 197 drumTracker.beatDistribution.likelihoodStdDev = drumTracker.arraySize / m.getArgAsFloat(0);
andrew@2 198 // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev);
andrew@2 199 }
andrew@2 200
andrew@2 201
andrew@2 202 }//end while there is new message
andrew@2 203
andrew@2 204
andrew@2 205 }
andrew@2 206
andrew@2 207
andrew@10 208 void testApp::newBeatInformation(const ofxOscMessage& m){
andrew@10 209
andrew@10 210 double timeNow = ofGetElapsedTimeMillis();
andrew@10 211 // if (timeNow - drumTracker.setBeatToNowTime > 1000)
andrew@10 212
andrew@10 213 int beatTime = round(m.getArgAsFloat(2));
andrew@10 214 recentError = m.getArgAsFloat(0);
andrew@10 215 int size = drumTracker.beatDistribution.arraySize;
andrew@10 216 int newIndex = round((size/2)+(recentError*size));
andrew@10 217 priorValue = drumTracker.beatDistribution.posterior[newIndex];
andrew@11 218
andrew@10 219 drumTracker.newKickError(m.getArgAsFloat(0), m.getArgAsFloat(2), m.getArgAsString(1));
andrew@10 220
andrew@10 221 KLdiv = drumTracker.beatDistribution.getKLdivergence();
andrew@10 222 entropy = drumTracker.beatDistribution.getEntropyOfPosterior();
andrew@11 223 priorEntropy = drumTracker.beatDistribution.getEntropyOfPrior();
andrew@10 224
andrew@10 225 drumType = m.getArgAsString(1);
andrew@10 226 int drumIndicator = 2;
andrew@10 227 if (drumType == "kick")
andrew@10 228 drumIndicator = 1;
andrew@10 229
andrew@10 230
andrew@10 231 beatPosition = m.getArgAsFloat(3);
andrew@10 232 printf("NEW BEAT: time %f error %f, position %f, drum %s, ", beatTime, recentError, beatPosition, drumType.c_str());
andrew@10 233
andrew@11 234 printf("KL div %f, entropy %f prior Entropy %f prior value %f, ", KLdiv, entropy, priorEntropy, priorValue);
andrew@10 235
andrew@10 236 printf("tatum is %f\n", drumTracker.beatTimes.tatum );
andrew@10 237
andrew@10 238
andrew@10 239 if (outputFile.is_open()){
andrew@10 240 outputFile.precision(4);
andrew@11 241 outputFile << fixed << beatTime << ", " << drumIndicator << ", " << recentError << ", " << beatPosition << ", " ;
andrew@10 242 outputFile.precision(6);
andrew@11 243 outputFile << fixed << priorValue << ", " << KLdiv << ", " << entropy << ", " << priorEntropy << ", " << drumTracker.beatTimes.tatum << "\n";
andrew@10 244 }else{
andrew@10 245 printf("file not open\n");
andrew@10 246 }
andrew@10 247
andrew@10 248
andrew@10 249 }
andrew@10 250
andrew@10 251
andrew@2 252 void testApp::takePictureOfScreen(){
andrew@2 253 // grab a rectangle at 200,200, width and height of 300,180
andrew@2 254 img.grabScreen(0,0,screenWidth,screenHeight);
andrew@2 255 char fileName[255];
andrew@10 256 sprintf(fileName, "snapshot_%.3i.png", snapCounter);
andrew@2 257 img.saveImage(fileName);
andrew@2 258 //printf("saved %s\n", fileName);
andrew@2 259 snapCounter++;
andrew@2 260 bSnapshot = false;
andrew@2 261 }
andrew@2 262
andrew@2 263 /*
andrew@2 264 void testApp::setBeatDistribution(int beatPosition){
andrew@2 265 switch (beatPosition){
andrew@2 266 //early sixteenth is that the beat is a sixteenth earlier
andrew@2 267 case 0:
andrew@2 268 case 1:
andrew@2 269 case 11:
andrew@2 270 //i.e. these zones are interpreted as "on the beat"
andrew@2 271 beatDistribution.eighthNoteProportion = 0;
andrew@2 272 beatDistribution.earlySixteenthNoteProportion = 0;
andrew@2 273 beatDistribution.lateSixteenthNoteProportion = 0;
andrew@2 274 break;
andrew@2 275 //10 and 2 were here
andrew@2 276
andrew@2 277 case 2:
andrew@2 278 beatDistribution.eighthNoteProportion = 0;
andrew@2 279 beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
andrew@2 280 //i.e. a 25% chance it is early sixteenth - 75% that the beat actually lies here
andrew@2 281 beatDistribution.lateSixteenthNoteProportion = 0;
andrew@2 282 break;
andrew@2 283
andrew@2 284 case 3:
andrew@2 285 beatDistribution.eighthNoteProportion = 0;
andrew@2 286 beatDistribution.earlySixteenthNoteProportion = 0.3;//was 0.4 in Bayesian8 //half chance it is early
andrew@2 287 beatDistribution.lateSixteenthNoteProportion = 0;
andrew@2 288 break;
andrew@2 289
andrew@2 290 case 5:
andrew@2 291 case 6:
andrew@2 292 case 7:
andrew@2 293 beatDistribution.eighthNoteProportion = 0.3;//i.e. nearly half a chance we are on the 8th note
andrew@2 294 beatDistribution.earlySixteenthNoteProportion = 0;
andrew@2 295 beatDistribution.lateSixteenthNoteProportion = 0;
andrew@2 296 break;
andrew@2 297
andrew@2 298 case 4:
andrew@2 299 beatDistribution.eighthNoteProportion = 0;
andrew@2 300 beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
andrew@2 301 beatDistribution.lateSixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8
andrew@2 302 //chsanged to 0.2 and 0.1 then back
andrew@2 303 break;
andrew@2 304
andrew@2 305 case 8:
andrew@2 306 beatDistribution.eighthNoteProportion = 0;
andrew@2 307 beatDistribution.earlySixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8
andrew@2 308 beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
andrew@2 309 break;
andrew@2 310
andrew@2 311 case 9:
andrew@2 312 beatDistribution.eighthNoteProportion = 0;
andrew@2 313 beatDistribution.earlySixteenthNoteProportion = 0;
andrew@2 314 beatDistribution.lateSixteenthNoteProportion = 0.35;//was 0.4 in Bayesian8
andrew@2 315 break;
andrew@2 316
andrew@2 317 case 10:
andrew@2 318 beatDistribution.eighthNoteProportion = 0;
andrew@2 319 beatDistribution.earlySixteenthNoteProportion = 0;
andrew@2 320 beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.2 in Bayesian8
andrew@2 321 break;
andrew@2 322
andrew@2 323 }
andrew@2 324
andrew@2 325 }
andrew@2 326 */
andrew@2 327 //--------------------------------------------------------------
andrew@2 328 void testApp::draw(){
andrew@2 329 //--------------------------- lines
andrew@2 330 // a bunch of red lines, make them smooth if the flag is set
andrew@2 331
andrew@2 332
andrew@2 333
andrew@2 334 if (bSmooth){
andrew@2 335 ofEnableSmoothing();
andrew@2 336 }
andrew@2 337
andrew@2 338 switch (screenToDraw){
andrew@2 339 case 0:
andrew@2 340 drawBayesianDistribution();
andrew@2 341 break;
andrew@2 342 case 1:
andrew@2 343 drawTempoDistribution();
andrew@2 344 break;
andrew@2 345 case 2:
andrew@2 346 drawBeatMap();
andrew@2 347 break;
andrew@2 348 case 3:
andrew@2 349 // drawNormalisedLikelihood();
andrew@2 350 drawRestrictedTempoDistribution(tempoWindowMinimum, tempoWindowMaximum);
andrew@2 351 break;
andrew@2 352 case 4:
andrew@2 353 drawTempoData();
andrew@2 354 break;
andrew@2 355 case 5:
andrew@2 356 drawBeatProbabilityDistribution();
andrew@2 357 break;
andrew@2 358 case 6:
andrew@2 359 drawPosterior();
andrew@2 360 break;
andrew@2 361 case 7:
andrew@2 362 drawGreyscaleBayesianDistribution();
andrew@2 363 break;
andrew@2 364
andrew@2 365 }
andrew@2 366
andrew@2 367
andrew@2 368
andrew@2 369 if (bSnapshot == true){
andrew@2 370 takePictureOfScreen();
andrew@2 371 bSnapshot = false;
andrew@2 372 }
andrew@2 373
andrew@3 374
andrew@3 375
andrew@3 376 drawKLdivAndEntropy();
andrew@3 377
andrew@3 378 }//end draw
andrew@3 379
andrew@3 380
andrew@3 381 void testApp::drawKLdivAndEntropy(){
andrew@2 382 ofDrawBitmapString("KLdiv :"+ofToString(KLdiv, 3), 20, 40);
andrew@2 383 ofSetColor(200,0,0,160);
andrew@2 384 ofRect(0, ofGetHeight()*(1-KLdiv), 40, ofGetHeight()*KLdiv);
andrew@2 385
andrew@3 386 ofSetColor(0,0, 200, 160);
andrew@3 387 ofDrawBitmapString("Entropy :"+ofToString(entropy, 3), 20, 60);
andrew@3 388 double entropyDrawFactor = 0.1;
andrew@3 389 ofRect(60, ofGetHeight()*(1-entropy*entropyDrawFactor), 40, ofGetHeight()*entropy*entropyDrawFactor);
andrew@4 390
andrew@4 391 ofSetColor(100,0,200, 220);
andrew@4 392 ofDrawBitmapString("Error :"+ofToString(recentError, 3), 20, 80);
andrew@4 393 ofRect(120, ofGetHeight()*(1-fabs(recentError)), 40, ofGetHeight()*2*fabs(recentError));
andrew@4 394
andrew@8 395 ofDrawBitmapString("prior val :"+ofToString(priorValue, 3), 20, 100);
andrew@8 396
andrew@8 397
andrew@8 398
andrew@4 399 ofSetColor(100,0,100, 220);
andrew@4 400 ofDrawBitmapString(drumType, 20, 0);
andrew@4 401
andrew@3 402 }
andrew@2 403
andrew@2 404
andrew@2 405 void testApp::drawTempoData(){
andrew@2 406
andrew@2 407 ofSetColor(0xFFFF00);
andrew@2 408 //yellow line in centre
andrew@2 409 ofLine( 0, (screenHeight/2), screenWidth, (screenHeight/2));
andrew@2 410
andrew@2 411 ofSetColor(0x0000FF);
andrew@2 412 int tempoIndex = 0;
andrew@2 413 int widthOffset = 20;
andrew@2 414 float stepWidth = screenWidth / 16;
andrew@2 415 ofDrawBitmapString("tatums : ", 600,180);
andrew@2 416 ofDrawBitmapString(ofToString(drumTracker.beatTimes.tatum, 1), 700,180);
andrew@2 417 ofDrawBitmapString("bpm : ", 600,200);
andrew@2 418 ofDrawBitmapString(ofToString((drumTracker.beatTimes.tatum/30000), 1), 700,200);
andrew@2 419 int intervalIndex;
andrew@2 420 int intervalWidth = 2;
andrew@2 421 float magnifyingFactor = 8;
andrew@2 422 for (tempoIndex = 0;tempoIndex < 16; tempoIndex++){
andrew@2 423
andrew@2 424 for (intervalIndex = 0;intervalIndex < 16;intervalIndex++){
andrew@2 425 //new color code
andrew@2 426 if (drumTracker.beatTimes.intervalUsed[tempoIndex][intervalIndex] == true){
andrew@2 427 ofSetColor(0x00FFFF);
andrew@2 428 }
andrew@2 429 else{
andrew@2 430 ofSetColor(0xFF00FF);
andrew@2 431 }
andrew@2 432 //end new code
andrew@2 433
andrew@2 434 ofLine((stepWidth*tempoIndex)+ (intervalWidth*intervalIndex) + widthOffset, screenHeight,
andrew@2 435 (stepWidth*tempoIndex) + (intervalWidth*intervalIndex) + widthOffset, (screenHeight/2) * (1 + (magnifyingFactor * (1-drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex]))));
andrew@2 436
andrew@2 437 if (printInterval == true){
andrew@2 438 ofDrawBitmapString(ofToString(drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex], 3),
andrew@2 439 (stepWidth*tempoIndex) + widthOffset,20+(intervalIndex*20));
andrew@2 440 }
andrew@2 441
andrew@2 442
andrew@2 443 ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][0], 3), 700,220+(tempoIndex*20));
andrew@2 444 ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][1], 1), 750,220+(tempoIndex*20));
andrew@2 445 }//end for interval index
andrew@2 446 }//end for tempo index
andrew@2 447
andrew@2 448 ofDrawBitmapString(ofToString(drumTracker.beatTimes.clickIndex), 750,20);
andrew@2 449
andrew@2 450 ofDrawBitmapString(ofToString(mouseBPM), 50,20);
andrew@2 451 ofDrawBitmapString(drumTracker.tempoDataString, 50, 100);
andrew@2 452
andrew@2 453 }//end draw tempo data
andrew@2 454
andrew@2 455
andrew@2 456 void testApp::drawTempoDistribution(){
andrew@10 457 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 458 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize));
andrew@10 459 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize));
andrew@2 460
andrew@2 461 maximum *= 1.1;
andrew@2 462
andrew@2 463 float stepHeight = screenHeight/maximum;
andrew@2 464
andrew@2 465
andrew@2 466
andrew@2 467 //draw prior in green
andrew@2 468 ofSetColor(0x888888);
andrew@10 469 for (int i = 1; i < drumTracker.arraySize; i+=2){
andrew@2 470 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight));
andrew@2 471 }
andrew@2 472
andrew@2 473
andrew@2 474 //draw posterior in dark
andrew@2 475 ofSetColor(0x000000);
andrew@10 476 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 477 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight));
andrew@2 478 }
andrew@2 479
andrew@2 480
andrew@2 481 //black line is the max probability
andrew@2 482 ofSetColor(0x000000);
andrew@2 483 ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0);
andrew@2 484
andrew@2 485 //blue is the current kick received
andrew@2 486 ofSetColor(0xAAAAAA);
andrew@2 487
andrew@2 488 int altIndex = 0;
andrew@2 489 for (altIndex = 0;altIndex< 16;altIndex++){
andrew@2 490
andrew@2 491 double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex];
andrew@2 492
andrew@2 493 if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){
andrew@2 494
andrew@2 495
andrew@2 496
andrew@2 497 //draw likelihood
andrew@2 498 //draw likelhood in blue
andrew@2 499 // //need to reset likelihood for this!
andrew@2 500 //XXX remove
andrew@2 501 double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex];
andrew@2 502 if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum)
andrew@2 503 {
andrew@2 504
andrew@10 505 ofLine(stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), screenHeight,
andrew@10 506 stepSize*(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 0);
andrew@2 507
andrew@10 508 drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
andrew@10 509 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 510 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight));
andrew@2 511 }
andrew@2 512 }
andrew@2 513
andrew@2 514 }
andrew@2 515
andrew@2 516 }//end for
andrew@2 517
andrew@2 518 if (bSmooth){
andrew@2 519 ofDisableSmoothing();
andrew@2 520 }
andrew@2 521
andrew@2 522 drawTempoInfo();
andrew@2 523
andrew@2 524 }
andrew@2 525
andrew@2 526
andrew@2 527 int testApp::xcoordinateFromTempoDataPoint(float f){
andrew@2 528 //f is the time
andrew@2 529
andrew@2 530 int xcoordinateForInterval = 0;
andrew@2 531 if (f >= drumTracker.tempoMinimum && f <= drumTracker.tempoMaximum)
andrew@2 532 xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum)*screenWidth/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum));
andrew@2 533 return xcoordinateForInterval;
andrew@2 534
andrew@2 535 }
andrew@2 536
andrew@2 537
andrew@2 538 int testApp::xcoordinateFromRestrictedTempoDataPoint(float f, const int& tmpMin, const int& tmpMax){
andrew@2 539
andrew@2 540
andrew@2 541 int xcoordinateForInterval = -1;
andrew@2 542 if (f >= drumTracker.tempoMinimum+tmpMin && f <= min(drumTracker.tempoMinimum+tmpMax,drumTracker.tempoMaximum))
andrew@2 543 xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum - tmpMin*arrayToMsecScaleFactor)*screenWidth/(float)((tmpMax - tmpMin)*arrayToMsecScaleFactor));
andrew@2 544 return xcoordinateForInterval;
andrew@2 545
andrew@2 546 }
andrew@2 547
andrew@2 548
andrew@2 549 void testApp::drawTempoInfo(){
andrew@10 550 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 551 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize));
andrew@10 552 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize));
andrew@2 553
andrew@2 554
andrew@2 555 ofSetColor(0x000000);
andrew@2 556 string testString;
andrew@2 557 testString = "max is ";
andrew@2 558 testString += ofToString(maximum);
andrew@2 559 ofDrawBitmapString(testString, 700,620);
andrew@2 560
andrew@2 561 ofDrawBitmapString(msg_string, 700,650);
andrew@2 562
andrew@2 563 ofDrawBitmapString(kickString, 700,670);
andrew@2 564
andrew@2 565 testString = "std dev : ";
andrew@2 566 testString += ofToString(drumTracker.tempoStdDev, 6);
andrew@2 567
andrew@2 568 testString += ", ";
andrew@2 569 testString += ofToString(drumTracker.accompanimentStarted);
andrew@2 570 ofDrawBitmapString(testString, 20, 120);
andrew@2 571
andrew@2 572 int tempoUpdateIndex;
andrew@2 573 for (tempoUpdateIndex = 0;tempoUpdateIndex<16;tempoUpdateIndex++){
andrew@2 574 // ofDrawBitmapString(tempoUpdateStrings[tempoUpdateIndex], 700, 200 + (20 * tempoUpdateIndex));
andrew@2 575 }
andrew@2 576
andrew@2 577 ofDrawBitmapString("Mouse located at tempo: ", 50,10);
andrew@2 578 ofDrawBitmapString(ofToString(mouseBPM, 1), 50,20);
andrew@2 579
andrew@2 580 ofDrawBitmapString("Current tempo: ", 50,40);
andrew@2 581 ofDrawBitmapString(ofToString(30000/drumTracker.beatTimes.tatum, 1), 50,50);
andrew@2 582
andrew@2 583 ofDrawBitmapString(drumTracker.tempoDataString, 50, 100);
andrew@2 584
andrew@2 585
andrew@2 586 for (int i = 1;i < 16; i++){
andrew@2 587 for (int altIndex = 0; altIndex < 16;altIndex++){
andrew@2 588 string newString;
andrew@2 589 newString = " :";
andrew@2 590 int recentIndex = (altIndex-i+16)%16;
andrew@2 591 if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){
andrew@2 592
andrew@2 593
andrew@2 594 int xcoordinateForInterval = xcoordinateFromTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex]);
andrew@2 595 float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2;
andrew@2 596
andrew@2 597 if (drumTracker.beatTimes.OnsetIsKick[altIndex])
andrew@2 598 ofSetColor(255*(8-beatInterval)/(float)8, 0, 255*beatInterval/(float)8);
andrew@2 599 else
andrew@2 600 ofSetColor(0, 255*(8-beatInterval)/(float)8, 255*beatInterval/(float)8);
andrew@2 601 //red kick, green snare
andrew@2 602
andrew@2 603 ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3);
andrew@2 604
andrew@2 605 newString += ofToString(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex],0);
andrew@2 606 newString += " (";
andrew@2 607 newString += ofToString(drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0);
andrew@2 608 newString += ")";
andrew@2 609
andrew@2 610 }
andrew@2 611 ofSetColor(0,0,0);
andrew@2 612 //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20));
andrew@2 613
andrew@2 614
andrew@2 615 }
andrew@2 616 }
andrew@2 617
andrew@2 618 }
andrew@2 619
andrew@2 620
andrew@2 621
andrew@2 622
andrew@2 623 void testApp::drawTempoDataPoints(const int& tmpMin, const int& tmpMax, const float& tmpStepSize){
andrew@2 624
andrew@2 625 for (int i = 1;i < 16; i++){
andrew@2 626 for (int altIndex = 0; altIndex < 16;altIndex++){
andrew@2 627 // string newString;
andrew@2 628 // newString = " :";
andrew@2 629
andrew@2 630 int recentIndex = (altIndex-i+16)%16;
andrew@2 631 if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){
andrew@2 632
andrew@2 633 int xcoordinateForInterval = xcoordinateFromRestrictedTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex], tmpMin, tmpMax);
andrew@2 634 float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2;
andrew@2 635
andrew@2 636 if (drumTracker.beatTimes.OnsetIsKick[altIndex])
andrew@2 637 ofSetColor(255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7, 0);//100+155*(8-beatInterval)/(float)8
andrew@2 638 else
andrew@2 639 ofSetColor(0, 255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7);//, 155*beatInterval/(float)8);
andrew@2 640 //red kick, green snare
andrew@2 641
andrew@2 642 ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3);
andrew@2 643 ofDrawBitmapString(ofToString(beatInterval, 0), xcoordinateForInterval-2, 200 + (altIndex * 20) - 3);
andrew@2 644 /* newString += ofToString(beatTimes.intervalDifferences[altIndex][recentIndex],0);
andrew@2 645 newString += " (";
andrew@2 646 newString += ofToString(beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0);
andrew@2 647 newString += ")";
andrew@2 648 */
andrew@2 649 }
andrew@2 650 ofSetColor(0,0,0);
andrew@2 651 //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20));
andrew@2 652
andrew@2 653
andrew@2 654 }
andrew@2 655 }
andrew@2 656
andrew@2 657 }
andrew@2 658
andrew@2 659
andrew@2 660 void testApp::drawRestrictedTempoDistribution(int tmpMin, int tmpMax){
andrew@2 661 //min and max are in the tempo array coordinates
andrew@2 662
andrew@2 663 tmpMin = max(tmpMin, 0);
andrew@10 664 tmpMax = min(tmpMax, drumTracker.arraySize-1);
andrew@2 665
andrew@10 666 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 667 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize));
andrew@10 668 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize));
andrew@2 669
andrew@2 670 maximum *= 1.1;
andrew@2 671
andrew@2 672 float stepHeight = screenHeight/maximum;
andrew@2 673 int tmpWidth = tmpMax - 1 - tmpMin;
andrew@2 674 float tmpStepSize = screenWidth / (float) tmpWidth;
andrew@2 675
andrew@2 676
andrew@2 677 //draw prior in green
andrew@2 678 ofSetColor(0x888888);
andrew@2 679 for (int i = 1; i < tmpWidth; i+=2){
andrew@2 680 ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i-1]*stepHeight), i * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i]*stepHeight));
andrew@2 681 }
andrew@2 682
andrew@2 683
andrew@2 684 //draw posterior in dark
andrew@2 685 ofSetColor(0x000000);
andrew@2 686 for (int i = 1; i < tmpWidth; i++){
andrew@2 687 ofLine((i-1) * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i]*stepHeight));
andrew@2 688 }
andrew@2 689
andrew@2 690
andrew@2 691 //black line is the max probability
andrew@2 692 ofSetColor(0x000000);
andrew@2 693 ofLine((drumTracker.tempoDistribution.integratedEstimate - tmpMin)* tmpStepSize, screenHeight, (drumTracker.tempoDistribution.integratedEstimate-tmpMin) *tmpStepSize, 0);
andrew@2 694
andrew@2 695 //blue is the current kick received
andrew@2 696 ofSetColor(0xAAAAAA);
andrew@2 697
andrew@2 698 int altIndex = 0;
andrew@2 699 for (altIndex = 0;altIndex< 16;altIndex++){
andrew@2 700 //iterate through all recent beat intervals
andrew@2 701
andrew@2 702 double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex];
andrew@2 703
andrew@2 704 if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){
andrew@2 705
andrew@2 706 double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex];
andrew@2 707
andrew@2 708 if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum){
andrew@2 709 //i.e. within the beat range only
andrew@2 710 //so we only draw the likelihood realtime for happening beat intervals
andrew@2 711 //in fact much more is going on than this but harder to visualise
andrew@2 712
andrew@10 713 float indexOfNewLocation = drumTracker.arraySize*(tempoInterval-drumTracker.tempoMinimum)/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum);
andrew@2 714
andrew@2 715
andrew@2 716 if (indexOfNewLocation >= tmpMin){
andrew@2 717 ofLine(tmpStepSize * (indexOfNewLocation-tmpMin), screenHeight, tmpStepSize * (indexOfNewLocation-tmpMin) , 0);
andrew@2 718 }
andrew@2 719
andrew@2 720
andrew@10 721 drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
andrew@2 722 //setting the tempo distribution likeihood just for visualisation purposes
andrew@2 723 for (int i = 1; i < tmpWidth; i++){
andrew@2 724 ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin]*stepHeight));
andrew@2 725
andrew@2 726 }
andrew@2 727 }
andrew@2 728
andrew@2 729 }
andrew@2 730
andrew@2 731 }//end for
andrew@2 732
andrew@2 733 if (bSmooth){
andrew@2 734 ofDisableSmoothing();
andrew@2 735 }
andrew@2 736
andrew@2 737
andrew@2 738 drawTempoDataPoints(tmpMin, tmpMax, tmpStepSize);
andrew@2 739
andrew@2 740 // lines for background
andrew@2 741 for (int i = tmpMin-(tmpMin%20);i < tmpMax; i+=20){
andrew@2 742 ofSetColor(0,0,200,100);
andrew@2 743 ofLine(tmpStepSize * (i-tmpMin), screenHeight, tmpStepSize * (i-tmpMin) , 0);
andrew@2 744 string tmpTempoString = ofToString(drumTracker.tempoMinimum + i*arrayToMsecScaleFactor, 0);
andrew@2 745 ofDrawBitmapString(tmpTempoString, tmpStepSize * (i-tmpMin) , 20);
andrew@2 746 }
andrew@2 747
andrew@2 748 string currentTatumString = "Beat Period : ";
andrew@2 749 currentTatumString += ofToString(drumTracker.beatTimes.tatum, 1);
andrew@2 750 currentTatumString += " MaxIndex : ";
andrew@2 751 currentTatumString += ofToString(drumTracker.tempoDistribution.integratedEstimate, 1);
andrew@2 752
andrew@2 753 ofDrawBitmapString(currentTatumString, 20, 40);
andrew@2 754 //drawTempoInfo();
andrew@2 755
andrew@2 756 }
andrew@2 757
andrew@2 758
andrew@2 759
andrew@2 760
andrew@2 761
andrew@2 762
andrew@2 763
andrew@2 764
andrew@2 765
andrew@2 766
andrew@2 767
andrew@2 768 void testApp::drawBeatMap(){
andrew@2 769 int x,y;
andrew@2 770
andrew@2 771 for (x=0;x < 6;x++){
andrew@2 772 for (y=0;y<8;y++){
andrew@2 773 int cell = x+(y*6);
andrew@2 774 if (cell == drumTracker.beatTimes.beatSegment){
andrew@2 775 if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick
andrew@2 776 ofSetColor(drumTracker.beatTimes.beatMap[cell]*255, 0, 0);
andrew@2 777
andrew@2 778 if (drumTracker.beatTimes.beatMap[cell] == 2)//for kick
andrew@2 779 ofSetColor(0, drumTracker.beatTimes.beatMap[cell]*255, 100);
andrew@2 780
andrew@2 781 }
andrew@2 782 else{
andrew@2 783 if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick
andrew@2 784 ofSetColor(drumTracker.beatTimes.beatMap[cell]*155, 0, 0);
andrew@2 785 else //for snare
andrew@2 786 ofSetColor(0,drumTracker.beatTimes.beatMap[cell]*155, 0);//beatTimes.beatMap[cell]*155);
andrew@2 787
andrew@2 788 }
andrew@2 789 ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8);
andrew@2 790
andrew@2 791 ofSetColor(255,0,0);
andrew@2 792 ofDrawBitmapString(ofToString(x+(y*6)), screenWidth*x/6, screenHeight*y/8);
andrew@2 793
andrew@2 794 if (drumTracker.beatTimes.beatMap[cell] == 1){
andrew@2 795 ofSetColor(0,255,255);//
andrew@2 796 ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) );
andrew@2 797 }
andrew@2 798 if (drumTracker.beatTimes.beatMap[cell] == 2){
andrew@2 799 ofSetColor(0,0,100);//
andrew@2 800 ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) );
andrew@2 801 }
andrew@2 802
andrew@2 803
andrew@2 804 }
andrew@2 805 }
andrew@2 806
andrew@2 807 }
andrew@2 808
andrew@2 809
andrew@2 810
andrew@2 811
andrew@2 812 void testApp::drawBeatProbabilityDistribution(){
andrew@2 813 int x,y;
andrew@2 814
andrew@2 815 for (x=0;x < 6;x++){
andrew@2 816 for (y=0;y<4;y++){
andrew@2 817 int cell = x+(y*6);
andrew@2 818 ofSetColor(drumTracker.beatTimes.beatProbabilityDistribution[y][x][0]*255, 0, 0);
andrew@2 819 ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8);
andrew@2 820 }
andrew@2 821 }
andrew@2 822 for (x=0;x < 6;x++){
andrew@2 823 for (y=0;y<4;y++){
andrew@2 824 int cell = x+(y*6);
andrew@2 825 ofSetColor(0, drumTracker.beatTimes.beatProbabilityDistribution[y][x][1]*255, 0);
andrew@2 826 ofRect(screenWidth*x/6, screenHeight*(y+4)/8, screenWidth/6, screenHeight/8);
andrew@2 827 }
andrew@2 828 }
andrew@2 829
andrew@2 830 }
andrew@2 831
andrew@2 832
andrew@2 833 void testApp::drawNormalisedLikelihood(){
andrew@10 834 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 835 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize));
andrew@10 836 //maximum = max(maximum, beatDistribution.getMaximum(&beatDistribution.posterior[0], drumTracker.arraySize));
andrew@2 837 float stepHeight = screenHeight/maximum;
andrew@2 838
andrew@2 839 if (!hidePriorMode){
andrew@2 840 //draw likelhood in blue
andrew@2 841
andrew@2 842 ofSetColor(0x0000FF);
andrew@10 843 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 844 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
andrew@2 845 }
andrew@2 846
andrew@2 847 //draw prior in green
andrew@2 848 ofSetColor(0x00AA00);
andrew@10 849 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 850 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
andrew@2 851 }
andrew@2 852 }//end hide prior mode
andrew@2 853
andrew@2 854
andrew@2 855
andrew@2 856 }
andrew@2 857
andrew@2 858
andrew@2 859
andrew@2 860 void testApp::drawPosterior(){
andrew@10 861 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize);
andrew@2 862
andrew@2 863 if (drumTracker.posteriorMaximum < maximum){
andrew@2 864 drumTracker.posteriorMaximum = 1.2*maximum;
andrew@2 865 }
andrew@2 866
andrew@2 867 float stepHeight = screenHeight/drumTracker.posteriorMaximum;
andrew@2 868 ofSetColor(0xFF00FF);
andrew@10 869 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 870 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
andrew@2 871 }
andrew@2 872
andrew@2 873
andrew@2 874 //yellow is the middle
andrew@2 875 ofSetColor(0xFFFF00);
andrew@10 876 ofLine(drumTracker.arraySize*stepSize/2, screenHeight, drumTracker.arraySize*stepSize/2, 0);
andrew@2 877
andrew@2 878
andrew@2 879
andrew@2 880 //blue is the current kick received
andrew@2 881 ofSetColor(0x0000FF);
andrew@10 882 ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), screenHeight,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), 0);
andrew@2 883
andrew@2 884 //purple line is the integrated max probability
andrew@2 885 int integratedBeatEstimateDrawPoint = round(drumTracker.beatDistribution.integratedEstimate*stepSize) ;
andrew@2 886 ofSetColor(0xFF22FF);
andrew@2 887 ofLine(integratedBeatEstimateDrawPoint, screenHeight, integratedBeatEstimateDrawPoint, 0);
andrew@2 888
andrew@2 889 string testString = "maximum: ";
andrew@2 890 testString += ofToString(drumTracker.posteriorMaximum, 2);
andrew@2 891 ofDrawBitmapString(testString, 100,120);
andrew@2 892
andrew@2 893
andrew@2 894 }
andrew@2 895
andrew@2 896
andrew@2 897
andrew@2 898
andrew@2 899
andrew@2 900 void testApp::drawBayesianDistribution(){
andrew@10 901 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 902 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize));
andrew@10 903 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize));
andrew@2 904 float stepHeight = screenHeight/maximum;
andrew@2 905
andrew@2 906 if (!hidePriorMode){
andrew@2 907 //draw likelhood in blue
andrew@2 908 if (drumTracker.onsetType == "kick")
andrew@2 909 ofSetColor(0xff0000);//red : kick
andrew@2 910 else
andrew@2 911 ofSetColor(0x00FF00);//green : snare
andrew@2 912
andrew@10 913 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 914 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
andrew@2 915 }
andrew@2 916
andrew@2 917 //;line where the current kick is received
andrew@10 918 ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), screenHeight,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), 0);
andrew@2 919
andrew@2 920
andrew@2 921 //draw prior in aqua blue
andrew@2 922 ofSetColor(0x00AAAA);
andrew@10 923 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 924 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
andrew@2 925 }
andrew@2 926 }//end hide prior mode
andrew@2 927
andrew@2 928 //draw posterior in red
andrew@2 929 ofSetColor(0x0000FF);
andrew@10 930 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 931 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
andrew@2 932 }
andrew@2 933
andrew@2 934 //draw the previous updated posteriror in purple
andrew@2 935 /* ofSetColor(0xFF22FF);
andrew@10 936 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 937 ofLine((i-1)*stepSize, screenHeight - (tmpArray[i-1]*stepHeight), i*stepSize, screenHeight - (tmpArray[i]*stepHeight));
andrew@2 938 }
andrew@2 939 */
andrew@2 940
andrew@2 941 //yellow is the middle
andrew@2 942 ofSetColor(0xFFFF00);
andrew@10 943 ofLine(drumTracker.arraySize*stepSize/2, screenHeight, drumTracker.arraySize*stepSize/2, 0);
andrew@2 944
andrew@2 945 //black line is the max probability
andrew@2 946 ofSetColor(0x000000);
andrew@2 947 ofLine(drumTracker.beatDistribution.maximumIndex*stepSize, screenHeight, drumTracker.beatDistribution.maximumIndex*stepSize, 0);
andrew@2 948
andrew@2 949
andrew@2 950 //purple line is the integrated max probability
andrew@2 951 int integratedBeatEstimate = drumTracker.beatDistribution.integratedEstimate ;
andrew@2 952 ofSetColor(0x2222FF);
andrew@2 953 ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0);
andrew@2 954
andrew@2 955
andrew@2 956 if (bSmooth){
andrew@2 957 ofDisableSmoothing();
andrew@2 958 }
andrew@2 959
andrew@2 960 printBayesianData();
andrew@2 961 }
andrew@2 962
andrew@2 963 void testApp::printBayesianData(){
andrew@2 964 //not optimised!!! XXX
andrew@10 965 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 966 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize));
andrew@10 967 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize));
andrew@2 968
andrew@2 969 ofSetColor(0x000000);
andrew@2 970 string testString;
andrew@2 971 testString = "max2 is ";
andrew@2 972 testString += ofToString(maximum, 3);
andrew@2 973 testString += " :: ";
andrew@2 974
andrew@2 975 testString = "correction of ";
andrew@2 976 testString += ofToString(drumTracker.beatCorrection);
andrew@2 977 testString += " corr by :";
andrew@2 978 testString += ofToString(drumTracker.correctBeatBy);
andrew@2 979
andrew@2 980 //ofDrawBitmapString(testString, 100,120);
andrew@2 981
andrew@2 982 testString = "MaxPhase ";
andrew@2 983 testString += ofToString(drumTracker.maxPhase);
andrew@2 984 // ofDrawBitmapString(testString, 100,140);
andrew@2 985
andrew@2 986
andrew@2 987 testString = "Likelihood noise ";
andrew@2 988 testString += ofToString(drumTracker.beatDistribution.likelihoodNoise, 2);
andrew@2 989 //ofDrawBitmapString(testString, 100,160);
andrew@2 990
andrew@2 991 // ofDrawBitmapString(msg_string, 100,140);
andrew@2 992
andrew@2 993 // ofDrawBitmapString(kickString, 100,180);
andrew@2 994
andrew@2 995 /* debugString = "Min Debug = ";
andrew@2 996 debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.minTempoIndex);
andrew@2 997 debugString += " Max Debug = ";
andrew@2 998 debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.maxTempoIndex);
andrew@2 999 */
andrew@2 1000 //ofDrawBitmapString(debugString, 300,370);
andrew@2 1001
andrew@2 1002 debugString = "CLICK INDEX = ";
andrew@2 1003 debugString += ofToString(drumTracker.beatTimes.clickIndex);
andrew@2 1004 //ofDrawBitmapString(debugString, 100, 20);
andrew@2 1005
andrew@2 1006 debugString = "STD DEV = ";
andrew@2 1007 debugString += ofToString(drumTracker.beatDistribution.standardDeviation, 2);
andrew@2 1008 // ofDrawBitmapString(debugString, 100, 40);
andrew@2 1009
andrew@2 1010
andrew@2 1011
andrew@2 1012 debugString = "interval ";
andrew@2 1013 debugString += ofToString(drumTracker.debugArray[2], 2);
andrew@2 1014 debugString += " time int = ";
andrew@2 1015 debugString += ofToString(drumTracker.debugArray[1], 2);
andrew@2 1016 debugString += " Beat max = ";
andrew@2 1017 debugString += ofToString(drumTracker.debugArray[0 ], 2);
andrew@2 1018 debugString += " Tempo max = ";
andrew@2 1019 debugString += ofToString(drumTracker.debugArray[3 ], 2);
andrew@2 1020 // ofDrawBitmapString(debugString, 300,570);
andrew@2 1021
andrew@2 1022 debugString = " last = ";
andrew@2 1023 debugString += ofToString(drumTracker.beatTimes.lastBeatTime, 2);
andrew@2 1024 // ofDrawBitmapString(debugString, 300,470);
andrew@2 1025
andrew@2 1026
andrew@2 1027 string closestClickString = "Closest Click ";
andrew@2 1028 closestClickString += ofToString(drumTracker.beatTimes.closestClickIndexToBeat[drumTracker.beatTimes.index]);
andrew@2 1029 closestClickString += " beat seg ";
andrew@2 1030 closestClickString += ofToString(drumTracker.beatTimes.beatSegment%12);
andrew@2 1031 closestClickString += " lastCindex";
andrew@2 1032 closestClickString += ofToString(drumTracker.beatTimes.lastClickIndex);
andrew@2 1033 closestClickString += " TD ";
andrew@2 1034 closestClickString += ofToString(drumTracker.beatTimes.timeDifference);
andrew@2 1035
andrew@2 1036 // ofDrawBitmapString(closestClickString, 100,100);
andrew@2 1037
andrew@2 1038 // ofDrawBitmapString(timeString, 100,60);
andrew@2 1039 }
andrew@2 1040
andrew@2 1041
andrew@2 1042
andrew@2 1043 void testApp::drawGreyscaleBayesianDistribution(){
andrew@2 1044 ofSetColor(255,255,255);
andrew@2 1045 ofRect(0,0,screenWidth, screenHeight);
andrew@2 1046
andrew@10 1047 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 1048 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize));
andrew@10 1049 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize));
andrew@2 1050 maximum *= 1.1;
andrew@2 1051 float stepHeight = screenHeight/maximum;
andrew@2 1052
andrew@2 1053 if (!hidePriorMode){
andrew@2 1054 //draw likelhood in blue
andrew@2 1055 ofSetColor(0x555555);
andrew@10 1056 for (int i = 1; i < drumTracker.arraySize; i+=2){
andrew@2 1057 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
andrew@2 1058 }
andrew@2 1059
andrew@2 1060 //draw prior in green
andrew@2 1061 ofSetColor(0xAAAAAA);
andrew@10 1062 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 1063 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
andrew@2 1064 }
andrew@2 1065 }//end hide prior mode
andrew@2 1066
andrew@2 1067 //draw posterior in dark grey
andrew@2 1068 ofSetColor(0x222222);
andrew@10 1069 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 1070 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
andrew@2 1071 }
andrew@2 1072
andrew@2 1073 /*
andrew@2 1074 //dotted the middle
andrew@2 1075 ofSetColor(0x555555);
andrew@2 1076 for (int i = 1; i < screenHeight; i+=4){
andrew@10 1077 ofLine(drumTracker.arraySize*stepSize/2, i, drumTracker.arraySize*stepSize/2, i-2);
andrew@2 1078 }
andrew@2 1079 */
andrew@2 1080
andrew@2 1081 //purple line is the integrated max probability
andrew@2 1082 // int integratedBeatEstimate = beatDistribution.integratedEstimate ;
andrew@2 1083 // ofSetColor(0x000000);
andrew@2 1084 // ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0);
andrew@2 1085
andrew@2 1086 //purple line is the integrated max probability
andrew@2 1087 float tmpIntegratedBeatEstimate = drumTracker.beatDistribution.getIntegratedEstimateIndex();
andrew@2 1088 ofSetColor(0x000000);
andrew@2 1089 int drawLinePoint = round(tmpIntegratedBeatEstimate *stepSize);
andrew@2 1090 ofLine(drawLinePoint, screenHeight, drawLinePoint, 0);
andrew@2 1091
andrew@2 1092 //blue is the current kick received
andrew@2 1093 ofSetColor(0x555555);
andrew@2 1094 for (int i = 1; i < screenHeight; i+=40){
andrew@10 1095 ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), i,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), i-20);
andrew@2 1096 }
andrew@2 1097
andrew@2 1098
andrew@2 1099 }
andrew@2 1100
andrew@2 1101
andrew@2 1102
andrew@2 1103
andrew@2 1104 void testApp::drawGreyscaleTempoDistribution(double tempoInterval){
andrew@2 1105 ofSetColor(255,255,255);
andrew@2 1106 ofRect(0,0,screenWidth, screenHeight);
andrew@2 1107
andrew@10 1108 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize);
andrew@10 1109 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize));
andrew@10 1110 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize));
andrew@2 1111
andrew@2 1112 maximum *= 1.1;
andrew@2 1113
andrew@2 1114 float stepHeight = screenHeight/maximum;
andrew@2 1115
andrew@2 1116 //draw prior in green
andrew@2 1117 ofSetColor(0x777777);
andrew@10 1118 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 1119 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight));
andrew@2 1120 }
andrew@2 1121
andrew@2 1122
andrew@2 1123 //draw posterior in dark
andrew@2 1124 ofSetColor(0x000000);
andrew@10 1125 for (int i = 1; i < drumTracker.arraySize; i++){
andrew@2 1126 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight));
andrew@2 1127 }
andrew@2 1128
andrew@2 1129
andrew@2 1130 //black line is the max probability
andrew@2 1131 ofSetColor(0xFF0000);
andrew@2 1132 ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0);
andrew@2 1133
andrew@2 1134 //blue is the current kick received
andrew@2 1135 ofSetColor(0xAAAAAA);
andrew@2 1136
andrew@2 1137
andrew@2 1138
andrew@2 1139
andrew@2 1140 for (int k =1;k < screenHeight/12;k+=2){
andrew@10 1141 ofLine(stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), 12*k,
andrew@10 1142 stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 12*(k-1));
andrew@2 1143 }
andrew@2 1144
andrew@10 1145 drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
andrew@10 1146 for (int i = 1; i < drumTracker.arraySize; i+=2){
andrew@2 1147 //dotted line likelihood fn
andrew@2 1148 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight));
andrew@2 1149 }
andrew@2 1150
andrew@2 1151
andrew@2 1152
andrew@2 1153
andrew@2 1154 if (bSmooth){
andrew@2 1155 ofDisableSmoothing();
andrew@2 1156 }
andrew@2 1157
andrew@2 1158 }
andrew@2 1159
andrew@2 1160
andrew@2 1161
andrew@2 1162
andrew@2 1163 //--------------------------------------------------------------
andrew@2 1164 void testApp::keyPressed (int key){
andrew@2 1165 if (key == 's'){
andrew@2 1166 bSmooth = !bSmooth;
andrew@2 1167 }
andrew@11 1168 if (key == 'n'){
andrew@11 1169 if (outputFile.is_open()){
andrew@11 1170 outputFile.close();
andrew@11 1171 }
andrew@11 1172 outputFile.open("../../../data/baydrumTest.txt");
andrew@11 1173
andrew@11 1174 }
andrew@11 1175
andrew@2 1176 if (key == 'x'){
andrew@2 1177 printInterval = !printInterval;
andrew@2 1178 }
andrew@2 1179
andrew@2 1180
andrew@2 1181 if (key == 'y'){
andrew@2 1182 drawData = !drawData;
andrew@2 1183 }
andrew@2 1184
andrew@2 1185 if (key == 'f'){
andrew@2 1186 ofToggleFullscreen();
andrew@2 1187 }
andrew@2 1188
andrew@2 1189 if (key == 'h' || key == 'H'){
andrew@2 1190 hidePriorMode = !hidePriorMode;//drawData;
andrew@2 1191 }
andrew@2 1192
andrew@2 1193
andrew@2 1194
andrew@2 1195 if ( key =='a' || key == 'A' )
andrew@2 1196 {
andrew@2 1197
andrew@2 1198 }
andrew@2 1199
andrew@2 1200 if (key == ' '){
andrew@2 1201 drumTracker.paused = !drumTracker.paused;
andrew@2 1202 }
andrew@2 1203
andrew@2 1204 if (key == OF_KEY_RIGHT){
andrew@2 1205 screenToDraw++;
andrew@2 1206 screenToDraw = screenToDraw % NUMBER_OF_SCREENS;
andrew@2 1207 }
andrew@2 1208 if (key == OF_KEY_LEFT){
andrew@2 1209 screenToDraw += NUMBER_OF_SCREENS - 1;
andrew@2 1210 screenToDraw = screenToDraw % NUMBER_OF_SCREENS;
andrew@2 1211 }
andrew@2 1212
andrew@2 1213 if (key == ']')
andrew@10 1214 drumTracker.beatDistribution.translateDistribution(drumTracker.arraySize / 4);
andrew@2 1215
andrew@2 1216 if (key == '[')
andrew@10 1217 drumTracker.beatDistribution.translateDistribution(-1*drumTracker.arraySize / 4);
andrew@2 1218
andrew@2 1219 if (key == 'x'){
andrew@2 1220 bSnapshot = true;
andrew@2 1221 }
andrew@2 1222
andrew@2 1223 if (key == 'q')
andrew@2 1224 drumTracker.adaptiveStandardDeviationMode = !drumTracker.adaptiveStandardDeviationMode;
andrew@2 1225
andrew@2 1226 }
andrew@2 1227
andrew@2 1228 /*
andrew@2 1229 void testApp::sendMaxTempo(){
andrew@2 1230 ofxOscMessage m;
andrew@2 1231 m.setAddress( "/tempo" );
andrew@2 1232
andrew@10 1233 //maxTempo = tempoDistribution.maximumIndex * (tempoMaximum - tempoMinimum) / drumTracker.arraySize;
andrew@2 1234 //would be introduced new in bayesian8
andrew@10 1235 maxTempo = drumTracker.tempoDistribution.getIntegratedEstimateIndex() * (tempoMaximum - tempoMinimum) / drumTracker.arraySize;
andrew@2 1236 maxTempo += tempoMinimum;
andrew@2 1237
andrew@2 1238
andrew@2 1239 m.addFloatArg( maxTempo );
andrew@2 1240 sender.sendMessage( m );
andrew@2 1241
andrew@2 1242 printf("max tempo %f\n", maxTempo);
andrew@2 1243
andrew@2 1244 }
andrew@2 1245
andrew@2 1246 void testApp::sendMaxPhase(){
andrew@2 1247
andrew@2 1248
andrew@10 1249 // maxPhase = (beatDistribution.maximumIndex - (drumTracker.arraySize/2)) / drumTracker.arraySize;
andrew@10 1250 maxPhase = (drumTracker.beatDistribution.getIntegratedEstimateIndex() - (drumTracker.arraySize/2)) / drumTracker.arraySize;
andrew@2 1251 printf("\nphase index %f :: %i\n", drumTracker.beatDistribution.integratedEstimate , maxPhase);
andrew@2 1252 ofxOscMessage m;
andrew@2 1253 m.setAddress( "/phase" );
andrew@2 1254 m.addFloatArg( maxPhase );
andrew@2 1255 sender.sendMessage( m );
andrew@2 1256
andrew@2 1257 //beatCorrection = maxPhase * beatTimes.tatum / 4;
andrew@2 1258 }
andrew@2 1259 */
andrew@2 1260 //--------------------------------------------------------------
andrew@2 1261 void testApp::keyReleased (int key){
andrew@2 1262
andrew@2 1263 }
andrew@2 1264
andrew@2 1265 //--------------------------------------------------------------
andrew@2 1266 void testApp::mouseMoved(int x, int y ){
andrew@2 1267
andrew@2 1268 mouseBPM = convertToBPM(drumTracker.tempoMinimum+ ((x * (drumTracker.tempoMaximum - drumTracker.tempoMinimum) ) / ofGetWidth() )) ;
andrew@2 1269 }
andrew@2 1270
andrew@2 1271 //--------------------------------------------------------------
andrew@2 1272 void testApp::mouseDragged(int x, int y, int button){
andrew@2 1273 }
andrew@2 1274
andrew@2 1275 //--------------------------------------------------------------
andrew@2 1276 void testApp::mousePressed(int x, int y, int button){
andrew@2 1277 }
andrew@2 1278
andrew@2 1279
andrew@2 1280 //--------------------------------------------------------------
andrew@2 1281 void testApp::mouseReleased(int x, int y, int button){
andrew@2 1282
andrew@2 1283 }
andrew@2 1284
andrew@2 1285 //--------------------------------------------------------------
andrew@2 1286 void testApp::windowResized(int w, int h){
andrew@2 1287 screenWidth = ofGetWidth();
andrew@2 1288 screenHeight = ofGetHeight();
andrew@10 1289 stepSize = screenWidth / (float)(drumTracker.arraySize);
andrew@2 1290 }
andrew@2 1291
andrew@2 1292 double testApp::convertToBPM(double interval){
andrew@2 1293 //interval is in ms and is the tatum interval - eighth nbote - so 250ms for 120bpm
andrew@2 1294 return (30000/interval);
andrew@2 1295
andrew@2 1296 }
andrew@2 1297 /*
andrew@2 1298 noyt needed?
andrew@2 1299 float testApp::tempoIndexToMsec(int index){
andrew@2 1300 float msec;
andrew@10 1301 msec = index * (tempoMaximum - tempoMinimum) / drumTracker.arraySize;
andrew@2 1302 msec += tempoMinimum;
andrew@2 1303 return msec;
andrew@2 1304 }
andrew@2 1305
andrew@2 1306 float testApp::beatIndexToMsec(int index){
andrew@2 1307 float msec;
andrew@10 1308 msec = index * maxTempo / drumTracker.arraySize;
andrew@2 1309 msec += tempoMinimum;
andrew@2 1310 return msec;
andrew@2 1311 }
andrew@2 1312 */
andrew@2 1313 /*
andrew@2 1314
andrew@2 1315 bool testApp::filterBeatTime(double newBeatTime){
andrew@2 1316 bool newBeatFound = false;
andrew@2 1317 if ((newBeatTime - beatTimes.lastBeatTime) > 20 || beatTimes.lastBeatTime == 0){
andrew@2 1318
andrew@2 1319 crossUpdateArrays((float)(newBeatTime - beatTimes.lastBeatTime));
andrew@2 1320 beatTimes.lastBeatTime = newBeatTime;
andrew@2 1321 newBeatFound = true;
andrew@2 1322 }
andrew@2 1323 return newBeatFound;
andrew@2 1324 }
andrew@2 1325
andrew@2 1326 void testApp::crossUpdateArrays(float timeInterval){
andrew@2 1327
andrew@2 1328 int finalBeatIndex, tmpTempoIndex, startBeatIndex;
andrew@2 1329 //finalBeat has contribution from BEAT[finalBeat + INT.k] * TEMPO[Max_tempo + k] where INT = INTERVAL
andrew@2 1330 float interval;
andrew@2 1331 interval = timeInterval / maxTempo;//beatTimes.tatum;
andrew@2 1332 tempoDistribution.resetMaximumPosterior();
andrew@2 1333 beatDistribution.resetMaximumPosterior();
andrew@2 1334
andrew@2 1335
andrew@2 1336 int tmpBeatIndex;
andrew@2 1337 //&& interval > 0.8 idea?
andrew@2 1338 if (timeInterval > 0 && timeInterval < 12000 ){//need between 0 and 12 seconds only to update
andrew@2 1339
andrew@10 1340 for (tmpBeatIndex = 0;tmpBeatIndex < drumTracker.arraySize;tmpBeatIndex++){
andrew@2 1341
andrew@2 1342 tmpArray[tmpBeatIndex] = 0;
andrew@2 1343 float minusMsecToMakeUp = beatIndexToMsec(tmpBeatIndex) / interval;
andrew@10 1344 float plusMsecToMakeUp = beatIndexToMsec(drumTracker.arraySize - tmpBeatIndex) / interval;
andrew@10 1345 float convertMsecToTempoIndex = drumTracker.arraySize / (tempoMaximum - tempoMinimum) ;
andrew@2 1346
andrew@2 1347
andrew@2 1348 int minTempoIndex = -1 * (int)(minusMsecToMakeUp * convertMsecToTempoIndex);
andrew@2 1349 int maxTempoIndex = (int)(plusMsecToMakeUp * convertMsecToTempoIndex);
andrew@2 1350
andrew@2 1351
andrew@2 1352 if (tmpBeatIndex == beatDistribution.maximumIndex){
andrew@2 1353 minTmpDebug = tempoDistribution.maximumIndex + minTempoIndex;
andrew@2 1354 maxTmpDebug = tempoDistribution.maximumIndex + maxTempoIndex;
andrew@2 1355 debugArray[0] = beatDistribution.maximumIndex;//
andrew@2 1356 debugArray[1] = timeInterval;
andrew@2 1357 debugArray[2] = interval;//beatDistribution.maximumIndex;
andrew@2 1358 debugArray[3] = tempoDistribution.maximumIndex;
andrew@2 1359 }
andrew@2 1360
andrew@2 1361 for (tmpTempoIndex = minTempoIndex;tmpTempoIndex <= maxTempoIndex;tmpTempoIndex++){
andrew@2 1362
andrew@2 1363 if ((tempoDistribution.maximumIndex + tmpTempoIndex) >= 0
andrew@10 1364 && (tempoDistribution.maximumIndex + tmpTempoIndex) < drumTracker.arraySize
andrew@2 1365 && (tmpBeatIndex - (int)(interval*tmpTempoIndex)) >= 0
andrew@10 1366 && (tmpBeatIndex - (int)(interval*tmpTempoIndex))< drumTracker.arraySize){
andrew@2 1367 tmpArray[tmpBeatIndex] += beatDistribution.posterior[tmpBeatIndex - (int)(interval*tmpTempoIndex)] * tempoDistribution.posterior[(int)tempoDistribution.maximumIndex + tmpTempoIndex];
andrew@2 1368 }
andrew@2 1369 }//end for tmpTmepo
andrew@2 1370
andrew@2 1371
andrew@2 1372
andrew@2 1373 }
andrew@2 1374
andrew@2 1375 float tmpFloat;
andrew@10 1376 for (tmpBeatIndex = 0;tmpBeatIndex < drumTracker.arraySize;tmpBeatIndex++){
andrew@2 1377 //debug - dont actually update::
andrew@2 1378
andrew@2 1379 tmpFloat = beatDistribution.posterior[tmpBeatIndex];
andrew@2 1380 beatDistribution.posterior[tmpBeatIndex] = tmpArray[tmpBeatIndex];
andrew@2 1381 tmpArray[tmpBeatIndex] = tmpFloat;
andrew@2 1382 }
andrew@10 1383 beatDistribution.renormaliseArray(&beatDistribution.posterior[0], drumTracker.arraySize);
andrew@2 1384
andrew@2 1385 } //end if
andrew@2 1386
andrew@2 1387
andrew@2 1388 }
andrew@2 1389
andrew@2 1390
andrew@2 1391 void testApp::updateTempoProcess(double cpuTime, string onsetDescription){
andrew@2 1392
andrew@2 1393 if (filterBeatTime(cpuTime) == true){
andrew@2 1394 //checks for no repeat
andrew@2 1395
andrew@2 1396 if (onsetDescription == "kick")
andrew@2 1397 beatTimes.addBeatTime(cpuTime, 1);
andrew@2 1398 else
andrew@2 1399 beatTimes.addBeatTime(cpuTime, 2);
andrew@2 1400
andrew@2 1401
andrew@2 1402 //recalculate the distribution
andrew@2 1403 int altIndex = 0;
andrew@2 1404
andrew@2 1405 tempoDataString = "Tatum :";
andrew@2 1406 tempoDataString += ofToString(beatTimes.tatum, 2);
andrew@2 1407 tempoDataString += " BPM ";
andrew@2 1408 tempoDataString += ofToString((double)30000/beatTimes.tatum, 2);
andrew@2 1409
andrew@2 1410 timeString = "Last BEAT ";
andrew@2 1411 timeString += ofToString(beatTimes.lastBeatTime);
andrew@2 1412 timeString += " CLICK ";
andrew@2 1413 timeString += ofToString(beatTimes.lastClickTime);
andrew@2 1414 timeString += " DIFDF ";
andrew@2 1415 timeString += ofToString(beatTimes.timeDifference);
andrew@2 1416 timeString += " segment ";
andrew@2 1417 timeString += ofToString(beatTimes.beatSegment);
andrew@2 1418
andrew@2 1419
andrew@2 1420 for (altIndex = 0;altIndex< 16;altIndex++){
andrew@2 1421 tempoInterval = beatTimes.intervalDifferences[beatTimes.index][altIndex];
andrew@2 1422 integerMultipleOfTatum = beatTimes.relativeIntervals[altIndex][1];
andrew@2 1423
andrew@2 1424
andrew@2 1425 ///NEW VERSION
andrew@2 1426 tempoUpdateStrings[altIndex] = "";
andrew@2 1427 double timeInterval = beatTimes.beatTimes[beatTimes.index] - beatTimes.beatTimes[altIndex];
andrew@2 1428 //raw time difference
andrew@2 1429 beatTimes.intervalDifferences[beatTimes.index][altIndex] = 0;
andrew@2 1430 beatTimes.intervalUsed[beatTimes.index][altIndex] = false;
andrew@2 1431
andrew@2 1432 if (onsetType == "kick")
andrew@2 1433 beatTimes.OnsetIsKick[beatTimes.index] = true;
andrew@2 1434 else
andrew@2 1435 beatTimes.OnsetIsKick[beatTimes.index] = false;
andrew@2 1436
andrew@2 1437
andrew@2 1438
andrew@2 1439 if (!accompanimentStarted){
andrew@2 1440 //if we need to find tempo and start use this method
andrew@2 1441 //we have 'started' once std dev is sufficiently low
andrew@2 1442
andrew@2 1443 updateTempoIfWithinRange(timeInterval);//taken as being the tatum interval
andrew@2 1444
andrew@2 1445
andrew@2 1446
andrew@2 1447 for (int i = 1;i <= 4;i++){
andrew@2 1448 //we test the main beats and the two bar (16 tatum intervals)
andrew@2 1449
andrew@2 1450 double testInterval = timeInterval / 2*i;//pow(2, i);//pow(2.0, i);
andrew@2 1451
andrew@2 1452 if (updateTempoIfWithinRange(testInterval)){
andrew@2 1453 printf("test time %f, beats %i\n", testInterval, i);
andrew@2 1454
andrew@2 1455 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
andrew@2 1456 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
andrew@2 1457 //xx what if two within range here?
andrew@2 1458
andrew@2 1459 tempoUpdateStrings[altIndex] = "Tempo Updates (";
andrew@2 1460 tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0);
andrew@2 1461 tempoUpdateStrings[altIndex] += ") : [";
andrew@2 1462 tempoUpdateStrings[altIndex] += ofToString(altIndex);
andrew@2 1463 tempoUpdateStrings[altIndex] += "]] : ";
andrew@2 1464 tempoUpdateStrings[altIndex] += ofToString(timeInterval);
andrew@2 1465 tempoUpdateStrings[altIndex] += ", ioi:";
andrew@2 1466 tempoUpdateStrings[altIndex] += ofToString(i);
andrew@2 1467 //tempoUpdateStrings[altIndex] += "";
andrew@2 1468
andrew@2 1469 }
andrew@2 1470
andrew@2 1471 }
andrew@2 1472
andrew@2 1473 double testInterval = timeInterval / 16;//pow(2, i);//pow(2.0, i);
andrew@2 1474 if (updateTempoIfWithinRange(testInterval)){
andrew@2 1475 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
andrew@2 1476 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
andrew@2 1477 }
andrew@2 1478
andrew@2 1479 }else{
andrew@2 1480 //OLD VERSON
andrew@2 1481 //THIS USES THE CURRENT TEMPO ESTIMATE TO DECIDE WHAT THE BEST INTERVAL IS
andrew@2 1482 //&& integerMultipleOfTatum % 2 == 0 removed below XXX put back
andrew@2 1483 if (altIndex != beatTimes.index && integerMultipleOfTatum < 17
andrew@2 1484 && integerMultipleOfTatum > 0 && beatTimes.startIndex > 8//beattimes.index > 8 - the start
andrew@2 1485 && integerMultipleOfTatum%2 == 0){//mod 2 - i.e. proper beat intervals only
andrew@2 1486
andrew@2 1487 double testInterval = timeInterval / integerMultipleOfTatum;
andrew@2 1488
andrew@2 1489 if (updateTempoIfWithinRange(testInterval)){
andrew@2 1490
andrew@2 1491 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
andrew@2 1492 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
andrew@2 1493
andrew@2 1494 if (paused == false){
andrew@2 1495 tempoUpdateStrings[altIndex] = "Tempo Updates : (";
andrew@2 1496 tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0);
andrew@2 1497 tempoUpdateStrings[altIndex] += ") : [";
andrew@2 1498 tempoUpdateStrings[altIndex] += ofToString(altIndex, 0);
andrew@2 1499 tempoUpdateStrings[altIndex] += "] :: ";
andrew@2 1500 tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum);
andrew@2 1501 tempoUpdateStrings[altIndex] += " intervals :: ";
andrew@2 1502 tempoUpdateStrings[altIndex] += ofToString(tempoInterval);
andrew@2 1503 tempoUpdateStrings[altIndex] += " ms.";
andrew@2 1504 // tempoUpdateStrings[altIndex] += ", ioi:";
andrew@2 1505
andrew@2 1506 // tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum);
andrew@2 1507
andrew@2 1508
andrew@2 1509
andrew@2 1510
andrew@2 1511 }//end if not paused
andrew@2 1512
andrew@2 1513
andrew@2 1514 }//end if good interval to update
andrew@2 1515
andrew@2 1516 }//end if not same index etc
andrew@2 1517
andrew@2 1518
andrew@2 1519 }
andrew@2 1520
andrew@2 1521
andrew@2 1522
andrew@2 1523 }//end for all intervals
andrew@2 1524
andrew@2 1525 sendMaxTempo();
andrew@2 1526 }//end if new beat time
andrew@2 1527 double tempoEstimate = tempoDistribution.getIntegratedEstimateIndex();
andrew@2 1528 tempoDistribution.calculateStandardDeviation();
andrew@2 1529 tempoStdDev = tempoDistribution.standardDeviation;
andrew@2 1530
andrew@2 1531 }
andrew@2 1532
andrew@2 1533
andrew@2 1534 bool testApp::updateTempoIfWithinRange(double timeInterval){
andrew@2 1535
andrew@2 1536 bool updated = false;
andrew@2 1537
andrew@2 1538 if (timeInterval > tempoMinimum && timeInterval < tempoMaximum ){
andrew@2 1539 calculateTempoUpdate(timeInterval);
andrew@2 1540 updated = true;
andrew@2 1541 }
andrew@2 1542
andrew@2 1543 return updated;
andrew@2 1544 }
andrew@2 1545
andrew@2 1546
andrew@2 1547 */
andrew@2 1548 //end
andrew@2 1549 /*
andrew@2 1550 void testApp::calculateTempoUpdate(double tempoInterval){
andrew@2 1551
andrew@2 1552
andrew@2 1553 tempoDistribution.resetPrior();
andrew@2 1554 //need to relook at likelihood for the tempo distribution - not the same as....
andrew@10 1555 tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval-tempoMinimum)/(tempoMaximum - tempoMinimum), tempoDistribution.likelihoodStdDev);
andrew@2 1556 tempoDistribution.calculatePosterior();
andrew@2 1557 tempoDistribution.renormalisePosterior();
andrew@2 1558
andrew@2 1559 //did take pic of screen here - see initialiser4
andrew@2 1560 }
andrew@2 1561 */
andrew@2 1562
andrew@6 1563 /*
andrew@6 1564 beatDistribution.initialiseArray();
andrew@6 1565 tempoDistribution.initialiseArray();
andrew@6 1566 beatTimes.lastBeatTime = 0;
andrew@6 1567 correctionFactor = 0.5;
andrew@6 1568
andrew@6 1569
andrew@6 1570
andrew@10 1571 tempoDistribution.likelihoodStdDev = drumTracker.arraySize / 32;
andrew@6 1572 // tempoDistribution.likelihoodNoise = 0.96;
andrew@6 1573 tempoDistribution.likelihoodNoise = 0.7;
andrew@10 1574 tempoDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/1);//wide
andrew@6 1575
andrew@10 1576 beatDistribution.likelihoodStdDev = drumTracker.arraySize / 32;
andrew@6 1577 beatDistribution.likelihoodNoise = 0.56;
andrew@10 1578 beatDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/1);
andrew@6 1579
andrew@6 1580
andrew@6 1581 tempoMinimum = 180;
andrew@6 1582 tempoMaximum = 400;
andrew@6 1583 posteriorMaximum = 0.1;
andrew@6 1584
andrew@6 1585 */
andrew@6 1586
andrew@6 1587 /*
andrew@6 1588 beatTimes.startIndex = 0;
andrew@6 1589 beatTimes.lastBeatTime = 0;
andrew@6 1590 maxPhase = 0;
andrew@6 1591 posteriorMaximum = 0.1;
andrew@6 1592
andrew@6 1593 accompanimentStarted = false;
andrew@6 1594
andrew@6 1595 tempoDistribution.likelihoodNoise = 0.8;
andrew@10 1596 tempoDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/2);//wide
andrew@6 1597
andrew@6 1598 beatDistribution.initialiseArray();
andrew@6 1599 tempoDistribution.initialiseArray();
andrew@6 1600
andrew@6 1601 tempoDistribution.calculateStandardDeviation();
andrew@6 1602 beatDistribution.calculateStandardDeviation();
andrew@6 1603
andrew@6 1604 tempoStdDev = tempoDistribution.standardDeviation;
andrew@6 1605
andrew@6 1606 beatTimes.resetBeatTimeArray();
andrew@6 1607 */