annotate src/midiEventHolder.cpp @ 3:de86d77f2612

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