annotate newOFsrc/testApp.cpp @ 5:4288150c257b

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