annotate src/midiEventHolder.cpp @ 5:195907bb8bb7

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