annotate src/midiEventHolder.cpp @ 4:4a8e6a6cd224

optimised draw function in dynamic vector class. Added Gaussian lookup but not yet used.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 19 Aug 2011 15:53:04 +0100
parents de86d77f2612
children 195907bb8bb7
rev   line source
andrew@0 1 /*
andrew@0 2 * midiEventHolder.cpp
andrew@0 3 * midiCannamReader3
andrew@0 4 *
andrew@0 5 * Created by Andrew on 19/07/2011.
andrew@0 6 * Copyright 2011 QMUL. All rights reserved.
andrew@0 7 *
andrew@0 8 */
andrew@0 9 //hello
andrew@0 10
andrew@0 11 #include "midiEventHolder.h"
andrew@0 12
andrew@0 13 midiEventHolder::midiEventHolder(){
andrew@0 14 // recordedNoteOnIndex = 0;
andrew@0 15
andrew@0 16 width = ofGetWidth();
andrew@0 17 height = ofGetHeight();
andrew@0 18 screenWidth= &width;
andrew@0 19 screenHeight = &height;
andrew@0 20
andrew@0 21 ticksPerScreen = 4000;
andrew@0 22 tickLocation = 0;
andrew@0 23 pulsesPerQuarternote = 240;
andrew@0 24 noteArrayIndex = 0;
andrew@0 25 noteMinimum = 30;
andrew@0 26 noteMaximum = 96;
andrew@0 27
andrew@4 28 minimumMatchSpeed = 0.0;
andrew@4 29 maximumMatchSpeed = 2.0;
andrew@2 30
andrew@0 31 likelihoodWidth = 100;
andrew@2 32 likelihoodToNoiseRatio = 0.02;
andrew@0 33
andrew@4 34 bayesStruct.speedLikelihoodNoise = 0.02;//was 0.05
andrew@2 35 bayesStruct.speedDecayWidth = 20;
andrew@2 36 bayesStruct.speedDecayAmount = 10;
andrew@2 37
andrew@3 38 speedPriorValue = 1.0;
andrew@2 39
andrew@2 40 matchWindowWidth = 8000;//window size for matching in ms
andrew@0 41
andrew@1 42 bayesStruct.resetSize(matchWindowWidth);
andrew@2 43 bayesStruct.setPositionDistributionScalar(1);
andrew@2 44
andrew@0 45 bayesStruct.resetSpeedSize(200);
andrew@0 46 bayesStruct.setRelativeSpeedScalar(0.01);
andrew@0 47 bayesStruct.relativeSpeedPrior.getMaximum();
andrew@2 48 //bayesStruct.simpleExample();
andrew@2 49
andrew@3 50 speedPriorValue = 1.0;
andrew@0 51 noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum);
andrew@4 52
andrew@4 53 printf("lookup index %f value %f\n", bayesStruct.prior.getLookupIndex(100, 30., 10.0), bayesStruct.prior.gaussianLookupTable[(int)bayesStruct.prior.getLookupIndex(100, 30., 10.0)]);
andrew@0 54 }
andrew@0 55
andrew@0 56
andrew@0 57
andrew@0 58 void midiEventHolder::reset(){
andrew@2 59 //called when we start playing
andrew@2 60
andrew@0 61 noteArrayIndex = 0;
andrew@0 62 tickLocation = 0;
andrew@0 63 lastPeriodUpdateTime = ofGetElapsedTimeMillis();
andrew@0 64 bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
andrew@0 65 numberOfScreensIn = 0;
andrew@0 66 // recordedNoteOnIndex = 0;
andrew@0 67 bayesStruct.setNewDistributionOffsets(0);
andrew@0 68 bayesStruct.posterior.offset = 0;
andrew@0 69
andrew@0 70 playedEventTimes.clear();
andrew@0 71 playedNoteOnMatrix.clear();
andrew@0 72 matchMatrix.clear();
andrew@0 73
andrew@0 74 bayesStruct.resetSpeedToOne();
andrew@3 75 bayesStruct.setSpeedPrior(speedPriorValue);
andrew@0 76
andrew@0 77 }
andrew@0 78
andrew@1 79 void midiEventHolder::clearAllEvents(){
andrew@1 80 recordedNoteOnMatrix.clear();
andrew@1 81 matchesFound.clear();
andrew@1 82 noteOnMatches.clear();
andrew@1 83 recordedEventTimes.clear();
andrew@1 84
andrew@1 85 //played events:
andrew@1 86 playedEventTimes.clear();
andrew@1 87 playedNoteOnMatrix.clear();
andrew@1 88 matchMatrix.clear();
andrew@1 89 }
andrew@1 90
andrew@0 91 void midiEventHolder::printNotes(){
andrew@0 92 printf("RECORDED MATRIX");
andrew@0 93 for (int i = 0;i < recordedNoteOnMatrix.size();i++){
andrew@0 94 printf("%i :: %i @ %f\n", recordedNoteOnMatrix[i][0], recordedNoteOnMatrix[i][1], recordedEventTimes[i]);
andrew@0 95 }
andrew@0 96 }
andrew@0 97
andrew@0 98
andrew@0 99 double midiEventHolder::getEventTimeTicks(double millis){
andrew@0 100 return (millis * pulsesPerQuarternote / period);
andrew@0 101 }
andrew@0 102
andrew@0 103 double midiEventHolder::getEventTimeMillis(double ticks){
andrew@0 104 return (period * ticks / (double) pulsesPerQuarternote);
andrew@0 105 }
andrew@0 106
andrew@0 107 void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){
andrew@0 108
andrew@0 109 //MOVE INTO BAYESSTRUCT?? XXX
andrew@0 110 //bayesStruct.copyPriorToPosterior();
andrew@0 111 //why was this here??
andrew@0 112 bayesStruct.prior.copyFromDynamicVector(bayesStruct.posterior);//try the otehr way
andrew@0 113 //bayesStruct.copyPriorToPosterior();
andrew@0 114 //need to get new MAP position and set the offset of the arrays
andrew@0 115 //currently bestEstimate is the approx for the new MAP position
andrew@0 116
andrew@0 117
andrew@0 118 //add the new event to our played information matrix
andrew@0 119 IntVector v;
andrew@0 120 v.push_back(pitch);
andrew@0 121 v.push_back(velocity);
andrew@0 122 playedNoteOnMatrix.push_back(v);
andrew@0 123
andrew@0 124
andrew@0 125 //would update the arrays at this point to show where out current location (phase) and tempo is.
andrew@2 126 // double timeNow = ofGetElapsedTimeMillis() - startTime;
andrew@2 127 double timeNow = timePlayed;// - startTime;
andrew@2 128 recentNoteOnTime = timePlayed;
andrew@0 129
andrew@2 130 // printf("Max time %f OF time %f \n", timePlayed, timeNow);
andrew@0 131
andrew@0 132 playedEventTimes.push_back(timePlayed);
andrew@0 133
andrew@2 134 // double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime;
andrew@2 135 double timeDifference = timePlayed - bayesStruct.lastEventTime;
andrew@0 136
andrew@2 137 printf("note %i played at %f and last event %f\n", pitch, timePlayed, bayesStruct.lastEventTime);
andrew@0 138 //addnoise to the tempo distribution
andrew@2 139 //bayesStruct.decaySpeedDistribution(timeDifference);
andrew@2 140 if (timeDifference > 50){
andrew@2 141 bayesStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10 / 100.);
andrew@2 142 // bayesStruct.addTriangularNoiseToSpeedPosterior(timeDifference * 10 / 100.);
andrew@2 143 }
andrew@2 144
andrew@2 145 bayesStruct.updateTmpBestEstimate(timeDifference);// debug - didnt work bayesStruct.bestEstimate = bayesStruct.tmpBestEstimate;
andrew@2 146 bayesStruct.updateBestEstimate();
andrew@2 147 bayesStruct.lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 148
andrew@0 149 // double newMAPestimateTime = bayesStruct.posterior.getIndexInRealTerms(bayesStruct.posterior.MAPestimate);
andrew@0 150 //was offset + bayesStruct.posterior.MAPestimate; but this doesnt include scalar to convert to millis
andrew@0 151
andrew@0 152 timeString = "Pitch:"+ofToString(pitch);
andrew@0 153 timeString += ", time now:"+ofToString(timeNow, 1);
andrew@0 154 timeString += " TD "+ofToString(timeDifference, 1);
andrew@0 155 timeString += " offset "+ofToString(bayesStruct.posterior.offset , 0);
andrew@0 156 timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0);
andrew@0 157 // timeString += " Previous time" + ofToString(newMAPestimateTime,0);
andrew@0 158 timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 2);
andrew@0 159 timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 2);
andrew@0 160
andrew@0 161 // newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
andrew@0 162 // timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0);
andrew@0 163
andrew@0 164 //then we recalculate the window start based on MAP being central
andrew@0 165 //then we do the matches on these and the likelihood on these.
andrew@0 166
andrew@0 167 bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)));
andrew@0 168 // bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
andrew@0 169
andrew@0 170 timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0);
andrew@0 171 timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1);
andrew@0 172 timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 1);
andrew@0 173 timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 1);
andrew@0 174
andrew@0 175
andrew@0 176 //be able to draw the prior in correct location relative to the midi notes
andrew@2 177 //this calculates the cross update of all possible speeds and all possible positions
andrew@0 178 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, timeDifference);
andrew@0 179
andrew@0 180
andrew@0 181 timeString += " new OFF "+ofToString(bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2), 1);
andrew@0 182 timeString += " notearrayindex "+ofToString(noteArrayIndex, 0);
andrew@0 183 //when this is off teh screen there is a problem somehow XXX
andrew@0 184 bayesStruct.posterior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
andrew@0 185 // bayesStruct.prior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
andrew@0 186 //trying to switch to prior
andrew@0 187
andrew@2 188 //bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
andrew@2 189 bayesStruct.lastEventTime = timePlayed;
andrew@0 190
andrew@0 191 //do the cross update to find current posterior for location
andrew@1 192 // totalConfidence= 0;
andrew@0 193 int numberOfMatchesFound = findLocalMatches(pitch);
andrew@0 194 setMatchLikelihoods(numberOfMatchesFound);
andrew@0 195 bayesStruct.calculatePosterior();
andrew@0 196
andrew@0 197 //having found matches we have matches for new note and matches for previous notes
andrew@0 198 findLocalTempoPairs();
andrew@0 199
andrew@2 200 //bayesStruct.addGaussianNoiseToSpeedPosterior(10);
andrew@0 201
andrew@0 202 }
andrew@0 203
andrew@0 204 int midiEventHolder::findLocalMatches(int notePitch){
andrew@0 205
andrew@0 206 //here we find the matches to the new note within appropriate range
andrew@0 207
andrew@1 208 matchString = "";
andrew@0 209
andrew@0 210 windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis
andrew@0 211 int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth);
andrew@0 212
andrew@1 213 matchString += " pitch: "+ofToString(notePitch)+" matches "+ofToString(numberOfMatches)+" win start "+ofToString(windowStartTime);
andrew@1 214
andrew@0 215 return numberOfMatches;
andrew@0 216
andrew@0 217
andrew@0 218 }
andrew@0 219
andrew@0 220
andrew@0 221 void midiEventHolder::setMatchLikelihoods(int numberOfMatches){
andrew@0 222 //reset the offset to match the prior
andrew@0 223 bayesStruct.likelihood.offset = bayesStruct.prior.offset;
andrew@0 224 bayesStruct.likelihood.zero();//set to zero
andrew@0 225
andrew@2 226 double quantity = likelihoodToNoiseRatio / numberOfMatches;
andrew@0 227
andrew@0 228 for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){
andrew@0 229 // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset);
andrew@0 230 //this is the vent time since start of file
andrew@0 231 if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){
andrew@1 232 // double confidenceMeasure = 0;
andrew@1 233 // if (totalConfidence > 0)
andrew@1 234 // confidenceMeasure = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[matchesFound[i]])/totalConfidence;
andrew@2 235
andrew@2 236 bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, quantity);//* confidenceMeasure
andrew@0 237 }//end if
andrew@0 238 }
andrew@2 239 bayesStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesStruct.likelihood.length);
andrew@0 240 }
andrew@0 241
andrew@0 242 int midiEventHolder::findMatch(const int& notePitch, const int& startTime, const int& endTime){
andrew@0 243
andrew@0 244 matchesFound.clear();
andrew@0 245 int startIndex = 0;
andrew@0 246
andrew@0 247 if (recordedEventTimes.size() > 0){
andrew@0 248
andrew@0 249 //get to the right range of events to check in
andrew@0 250 while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < startTime)
andrew@0 251 startIndex++;
andrew@0 252
andrew@0 253 }
andrew@0 254
andrew@0 255
andrew@0 256 while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < endTime){
andrew@0 257 if (recordedNoteOnMatrix[startIndex][1] == notePitch){
andrew@0 258 matchesFound.push_back(startIndex);
andrew@1 259 double confidence = bayesStruct.posterior.getValueAtMillis(mouseX);
andrew@1 260 // recordedEventTimes[startIndex]);
andrew@1 261 matchString += "["+ofToString(startIndex)+"] = "+ofToString(confidence, 3)+" .";
andrew@0 262 }
andrew@0 263 startIndex++;
andrew@0 264 }
andrew@0 265
andrew@0 266 // printf("%i MATCHES TO Note %i found\n", (int)matchesFound.size(), notePitch);
andrew@0 267 int size = matchesFound.size();
andrew@0 268
andrew@0 269 IntVector v;
andrew@0 270 v.push_back(size);
andrew@0 271 for (int i = 0;i < matchesFound.size();i++)
andrew@0 272 v.push_back(matchesFound[i]);
andrew@0 273
andrew@0 274 matchMatrix.push_back(v);
andrew@0 275
andrew@0 276 return size;
andrew@0 277 }
andrew@0 278
andrew@0 279 bool midiEventHolder::checkIfMatchedNote(const int& tmpIndex){
andrew@0 280 for (int i = 0;i < matchesFound.size();i++){
andrew@0 281 if (matchesFound[i] == tmpIndex)
andrew@0 282 return true;
andrew@0 283 }
andrew@0 284 return false;
andrew@0 285 }
andrew@0 286
andrew@0 287
andrew@0 288
andrew@0 289 void midiEventHolder::findLocalTempoPairs(){
andrew@0 290
andrew@0 291 int currentPlayedIndex = playedNoteOnMatrix.size()-1;
andrew@0 292 // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]);
andrew@0 293 // printMatchesFound();
andrew@0 294 // printMatchMatrix();
andrew@0 295 // printf("possible notes \n");
andrew@0 296
andrew@0 297
andrew@0 298 for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
andrew@0 299
andrew@0 300 int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1];
andrew@0 301
andrew@0 302 int previousIndex = currentPlayedIndex-1;
andrew@0 303
andrew@0 304 while (previousIndex >= 0 && playedEventTimes[previousIndex] + 2000 > playedEventTimes[currentPlayedIndex]) {
andrew@0 305 double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex];
andrew@0 306
andrew@0 307 for (int k = 0;k < matchMatrix[previousIndex][0];k++){
andrew@0 308 int recordedPreviousIndex = matchMatrix[previousIndex][k+1];
andrew@0 309
andrew@1 310
andrew@0 311
andrew@0 312 double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex];
andrew@1 313
andrew@0 314
andrew@0 315 //we want the speed of the recording relative to that of the playing live
andrew@0 316
andrew@0 317 double speedRatio = recordedTimeDifference / playedTimeDifference;
andrew@0 318 if (speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){
andrew@2 319 /*
andrew@2 320 printf("(%i)", matchMatrix[currentPlayedIndex][i+1]);
andrew@1 321 printf("[%i] :: ", recordedPreviousIndex);
andrew@1 322 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference);
andrew@1 323 printf("update on speed ratio %f\n", speedRatio);
andrew@2 324 */
andrew@1 325 // matchString += " speed: "+ofToString(speedRatio, 3);
andrew@0 326 // commented for debug
andrew@2 327
andrew@2 328 bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match
andrew@0 329
andrew@0 330 }
andrew@0 331 // printf("\n");
andrew@0 332 }
andrew@0 333
andrew@0 334 previousIndex--;
andrew@0 335 }//end while previousindex countdown
andrew@0 336 }//end for loop through possible current matches
andrew@0 337
andrew@2 338 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
andrew@0 339 }
andrew@0 340
andrew@0 341
andrew@0 342 void midiEventHolder::updatePlayPosition(){
andrew@0 343
andrew@0 344 //in actual fact if we are changing the speed of the play position
andrew@0 345 //we will need to update this via the file
andrew@0 346
andrew@0 347 double timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;
andrew@0 348 //this is time diff in milliseconds
andrew@0 349 //then we have
andrew@0 350 double quarterNoteIntervals = (timeDifference / period);
andrew@0 351 tickLocation = quarterNoteIntervals * pulsesPerQuarternote;
andrew@0 352
andrew@0 353 playPositionInMillis = timeDifference;//based on updating from when we change period
andrew@0 354 //this to be added
andrew@0 355
andrew@0 356 bayesStruct.updateBestEstimate();
andrew@0 357
andrew@0 358 }
andrew@0 359
andrew@0 360
andrew@0 361 void midiEventHolder::drawFile(){
andrew@0 362 //draws midi file on scrolling screen
andrew@0 363 int size = recordedNoteOnMatrix.size();
andrew@0 364 if (size > 0){
andrew@0 365
andrew@0 366 numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in
andrew@0 367
andrew@0 368 // numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down
andrew@0 369 timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen);
andrew@0 370
andrew@0 371 while (noteArrayIndex < recordedNoteOnMatrix.size() && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] )
andrew@0 372 noteArrayIndex++;
andrew@0 373
andrew@0 374
andrew@0 375 while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < recordedNoteOnMatrix[noteArrayIndex][0])
andrew@0 376 noteArrayIndex--;
andrew@0 377
andrew@0 378 //need to start where we currently are in file
andrew@0 379 int maxNoteIndexToPrint = noteArrayIndex;
andrew@0 380 int minNoteIndexToPrint = noteArrayIndex;
andrew@0 381
andrew@0 382 while (maxNoteIndexToPrint < recordedNoteOnMatrix.size() && recordedNoteOnMatrix[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen )
andrew@0 383 maxNoteIndexToPrint++;
andrew@0 384
andrew@0 385 while (minNoteIndexToPrint > 0 && minNoteIndexToPrint < size && recordedNoteOnMatrix[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)
andrew@0 386 minNoteIndexToPrint--;
andrew@0 387
andrew@0 388 for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)recordedNoteOnMatrix.size());tmpIndex++){
andrew@0 389
andrew@0 390 if (checkIfMatchedNote(tmpIndex))
andrew@0 391 ofSetColor(0,0,255);
andrew@0 392 else
andrew@0 393 ofSetColor(255,255,255);
andrew@0 394
andrew@0 395 // XXX replace ofgetwidth below
andrew@0 396 //if (tmpIndex >= 0 && tmpIndex < size)
andrew@0 397 int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen;
andrew@0 398 int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen;
andrew@0 399
andrew@0 400
andrew@0 401 int yLocation = (*screenHeight) - ((recordedNoteOnMatrix[tmpIndex][1] - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum));
andrew@0 402 ofRect(xLocation,yLocation, duration, noteHeight);
andrew@0 403
andrew@0 404 }
andrew@0 405
andrew@0 406
andrew@0 407 int xLocation;// = getLocationFromTicks(tickLocation);
andrew@0 408 // ofLine(xLocation, 0, xLocation, (*screenHeight));
andrew@0 409
andrew@0 410 //orange line at best estimate
andrew@0 411 xLocation = getLocationFromMillis(bayesStruct.bestEstimate);
andrew@0 412 ofSetColor(250,100,0);
andrew@0 413 ofLine(xLocation, 0, xLocation, (*screenHeight));
andrew@0 414
andrew@2 415 xLocation = getLocationFromMillis(bayesStruct.tmpBestEstimate);
andrew@2 416 ofSetColor(250,100,0);
andrew@2 417 ofLine(xLocation, 0, xLocation, (*screenHeight));
andrew@2 418
andrew@0 419
andrew@0 420 //lines where matching window start and end are
andrew@0 421 ofSetColor(0,100,255);
andrew@0 422 xLocation = getLocationFromMillis(windowStartTime);
andrew@0 423 ofLine(xLocation, 0, xLocation, (*screenHeight));
andrew@0 424 xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth);
andrew@0 425 ofLine(xLocation, 0, xLocation, (*screenHeight));
andrew@0 426
andrew@0 427
andrew@0 428 }
andrew@0 429
andrew@1 430
andrew@1 431
andrew@0 432 ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
andrew@0 433
andrew@0 434 ofDrawBitmapString(timeString, 20, 60);
andrew@0 435
andrew@0 436 // bayesStruct.drawArrays();
andrew@0 437
andrew@0 438 // ofSetColor(200,200,0);
andrew@0 439 // bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800);
andrew@0 440
andrew@0 441 //need to draw arrays within correct timescope
andrew@0 442 bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen));
andrew@0 443
andrew@1 444 if (drawTempoMode)
andrew@1 445 bayesStruct.drawTempoArrays();
andrew@0 446
andrew@1 447
andrew@1 448 ofSetColor(0, 0, 0);
andrew@0 449 ofDrawBitmapString(matchString, 20, ofGetHeight() - 20);
andrew@0 450
andrew@1 451 double confidence = bayesStruct.posterior.getValueAtMillis(mouseX);
andrew@2 452 /*
andrew@2 453 string mouseString = "mouseX "+ofToString(confidence, 3)+" .";
andrew@1 454 ofDrawBitmapString(mouseString, 20 , ofGetHeight() - 40);
andrew@2 455 */
andrew@2 456 string mouseString = "updateCounter "+ofToString(bayesStruct.updateCounter);
andrew@2 457 ofDrawBitmapString(mouseString, 20 , ofGetHeight() - 40);
andrew@2 458
andrew@2 459 string infostring = "speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 3);
andrew@2 460 ofDrawBitmapString(infostring, 20 , ofGetHeight() - 60);
andrew@0 461 }
andrew@0 462
andrew@0 463 int midiEventHolder::getLocationFromTicks(double tickPosition){
andrew@0 464 return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen);
andrew@0 465 }
andrew@0 466
andrew@0 467 int midiEventHolder::getLocationFromMillis(double millisPosition){
andrew@0 468 //(getEventTimeTicks(windowStartTime+matchWindowWidth) - numberOfScreensIn*ticksPerScreen)*(*screenWidth) / (double)ticksPerScreen
andrew@0 469 return (millisPosition - timeOffsetForScreen)*(*screenWidth)/getEventTimeMillis(ticksPerScreen);
andrew@0 470 }
andrew@0 471
andrew@0 472
andrew@0 473 void midiEventHolder::exampleCrossUpdate(){
andrew@0 474
andrew@0 475 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, 200);
andrew@0 476
andrew@0 477 }
andrew@0 478
andrew@0 479
andrew@0 480 void midiEventHolder::setStartPlayingTimes(){
andrew@0 481 lastPeriodUpdateTime = ofGetElapsedTimeMillis();
andrew@0 482 startTime = lastPeriodUpdateTime;
andrew@0 483
andrew@2 484 /*
andrew@2 485 bayesStruct.lastEventTime = 0;//ofGetElapsedTimeMillis();
andrew@2 486 bayesStruct.bestEstimate = 0;
andrew@0 487 bayesStruct.resetArrays();
andrew@2 488 bayesStruct.lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@2 489 */
andrew@2 490 bayesStruct.setStartPlaying();
andrew@0 491 matchString = "";
andrew@0 492 }
andrew@0 493
andrew@0 494
andrew@0 495 void midiEventHolder::printMatchMatrix(){
andrew@0 496 printf("match matrix:\n");
andrew@0 497 for (int i = 0;i < matchMatrix.size();i++){
andrew@0 498 for (int k = 0;k < matchMatrix[i].size();k++){
andrew@0 499 printf("%i , ", matchMatrix[i][k]);
andrew@0 500 }
andrew@0 501 printf("\n");
andrew@0 502 }
andrew@0 503
andrew@0 504
andrew@0 505 }