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