annotate src/midiEventHolder.cpp @ 1:1a32ce016bb9

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