comparison src/midiEventHolder.cpp @ 9:75dcd1308658

looked at tempo process, likelihood function changed and improved. Now drawing using constrained vector function. Good working version.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 23 Aug 2011 11:20:44 +0100
parents 6f5836d432ca
children 2ab6f4670cf5
comparison
equal deleted inserted replaced
8:d9a3613e7264 9:75dcd1308658
29 maximumMatchSpeed = 2.0; 29 maximumMatchSpeed = 2.0;
30 30
31 likelihoodWidth = 100; 31 likelihoodWidth = 100;
32 likelihoodToNoiseRatio = 0.02; 32 likelihoodToNoiseRatio = 0.02;
33 33
34 bayesStruct.speedLikelihoodNoise = 0.02;//was 0.05 34 bayesStruct.speedLikelihoodNoise = 0.1;//was 0.05
35 bayesStruct.speedDecayWidth = 20; 35 bayesStruct.speedDecayWidth = 20;
36 bayesStruct.speedDecayAmount = 10; 36 bayesStruct.speedDecayAmount = 10;
37 37
38 speedPriorValue = 1.0; 38 speedPriorValue = 1.0;
39 39
51 speedWindowWidthMillis = 4000; 51 speedWindowWidthMillis = 4000;
52 speedPriorValue = 1.0; 52 speedPriorValue = 1.0;
53 noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum); 53 noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum);
54 54
55 confidenceWeightingUsed = false; 55 confidenceWeightingUsed = false;
56
57 drawPhaseMode = true;
56 58
57 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)]); 59 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)]);
58 } 60 }
59 61
60 62
142 playedEventTimes.push_back(timePlayed); 144 playedEventTimes.push_back(timePlayed);
143 145
144 // double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime; 146 // double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime;
145 double timeDifference = timePlayed - bayesStruct.lastEventTime; 147 double timeDifference = timePlayed - bayesStruct.lastEventTime;
146 148
147 printf("note %i played at %f and last event %f\n", pitch, timePlayed, bayesStruct.lastEventTime); 149 // printf("note %i played at %f and last event %f\n", pitch, timePlayed, bayesStruct.lastEventTime);
148 //addnoise to the tempo distribution 150 //addnoise to the tempo distribution
149 //bayesStruct.decaySpeedDistribution(timeDifference); 151 //bayesStruct.decaySpeedDistribution(timeDifference);
150 if (timeDifference > 50){ 152 if (timeDifference > 50){
151 bayesStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10 / 100.); 153 bayesStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10 / 100.);
152 // bayesStruct.addTriangularNoiseToSpeedPosterior(timeDifference * 10 / 100.); 154 // bayesStruct.addTriangularNoiseToSpeedPosterior(timeDifference * 10 / 100.);
163 timeString += ", time now:"+ofToString(timeNow, 1); 165 timeString += ", time now:"+ofToString(timeNow, 1);
164 timeString += " TD "+ofToString(timeDifference, 1); 166 timeString += " TD "+ofToString(timeDifference, 1);
165 timeString += " offset "+ofToString(bayesStruct.posterior.offset , 0); 167 timeString += " offset "+ofToString(bayesStruct.posterior.offset , 0);
166 timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0); 168 timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0);
167 // timeString += " Previous time" + ofToString(newMAPestimateTime,0); 169 // timeString += " Previous time" + ofToString(newMAPestimateTime,0);
168 timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 2); 170 timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 2);
169 timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 2); 171 timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 2);
170 172
171 // newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); 173 // newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
172 // timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0); 174 // timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0);
173 175
174 //then we recalculate the window start based on MAP being central 176 //then we recalculate the window start based on MAP being central
177 bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2))); 179 bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)));
178 // bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)); 180 // bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
179 181
180 timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0); 182 timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0);
181 timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1); 183 timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1);
182 timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 1); 184 timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 1);
183 timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 1); 185 timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 1);
184 186
185 187
186 //be able to draw the prior in correct location relative to the midi notes 188 //be able to draw the prior in correct location relative to the midi notes
187 //this calculates the cross update of all possible speeds and all possible positions 189 //this calculates the cross update of all possible speeds and all possible positions
188 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, timeDifference); 190 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, timeDifference);
327 int currentPlayedIndex = playedNoteOnMatrix.size()-1; 329 int currentPlayedIndex = playedNoteOnMatrix.size()-1;
328 // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]); 330 // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]);
329 // printMatchesFound(); 331 // printMatchesFound();
330 // printMatchMatrix(); 332 // printMatchMatrix();
331 // printf("possible notes \n"); 333 // printf("possible notes \n");
334 bool needToUpdate = false;
335 bayesStruct.setLikelihoodToConstant();
332 336
333 337
334 for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){ 338 for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
335 //iterate through the recently matched events - even dodgy matches included 339 //iterate through the recently matched events - even dodgy matches included
336 //size, index of match0, index of match1, .... 340 //size, index of match0, index of match1, ....
341
342
337 int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1]; 343 int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1];
338 344
339 int previousIndex = currentPlayedIndex-1; 345 int previousIndex = currentPlayedIndex-1;
346
340 347
341 while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) { 348 while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) {
342 double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; 349 double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex];
343 350
344 for (int k = 0;k < matchMatrix[previousIndex][0];k++){ 351 for (int k = 0;k < matchMatrix[previousIndex][0];k++){
359 printf("update on speed ratio %f\n", speedRatio); 366 printf("update on speed ratio %f\n", speedRatio);
360 */ 367 */
361 // matchString += " speed: "+ofToString(speedRatio, 3); 368 // matchString += " speed: "+ofToString(speedRatio, 3);
362 // commented for debug 369 // commented for debug
363 370
364 bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match 371 //bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match
365 372 double amount = (1-bayesStruct.speedLikelihoodNoise)/10;
373 bayesStruct.updateTempoLikelihood(speedRatio, amount);
374 needToUpdate = true;
366 } 375 }
367 // printf("\n"); 376 // printf("\n");
368 } 377 }
369 378
370 previousIndex--; 379 previousIndex--;
371 }//end while previousindex countdown 380 }//end while previousindex countdown
372 }//end for loop through possible current matches 381 }//end for loop through possible current matches
373 382
383 if (needToUpdate)
384 bayesStruct.updateTempoDistribution();
385
374 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); 386 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
375 } 387 }
376 388
377 389
378 void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){ 390 void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){
391 bool needToUpdate = false;
379 392
380 int currentPlayedIndex = playedNoteOnMatrix.size()-1; 393 int currentPlayedIndex = playedNoteOnMatrix.size()-1;
381 // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]); 394 // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]);
382 // printMatchesFound(); 395 // printMatchesFound();
383 // printMatchMatrix(); 396 // printMatchMatrix();
384 // printf("possible notes \n"); 397 // printf("possible notes \n");
385 398
399 bayesStruct.setLikelihoodToConstant();
386 400
387 for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){ 401 for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
388 //iterate through the recently matched events - even dodgy matches included 402 //iterate through the recently matched events - even dodgy matches included
389 //size, index of match0, index of match1, .... 403 //size, index of match0, index of match1, ....
390 int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1]; 404 int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1];
416 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); 430 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference);
417 printf("update on speed ratio %f\n", speedRatio); 431 printf("update on speed ratio %f\n", speedRatio);
418 432
419 // matchString += " speed: "+ofToString(speedRatio, 3); 433 // matchString += " speed: "+ofToString(speedRatio, 3);
420 // commented for debug 434 // commented for debug
421 double weighting = previousMatchConfidence * currentMatchConfidence * 0.1; 435 double weighting = previousMatchConfidence * currentMatchConfidence ;
422 bayesStruct.updateTempoDistribution(speedRatio, weighting);//second paramter is confidence in the match 436 double amount = (1-bayesStruct.speedLikelihoodNoise)*weighting/10;
423 437 bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match
438 needToUpdate = true;
424 } 439 }
425 // printf("\n"); 440 // printf("\n");
426 } 441 }
427 442
428 previousIndex--; 443 previousIndex--;
429 }//end while previousindex countdown 444 }//end while previousindex countdown
430 }//end for loop through possible current matches 445 }//end for loop through possible current matches
431 446
447 if (needToUpdate)
448 bayesStruct.updateTempoDistribution();
432 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); 449 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
433 } 450 }
434 451
435 452
436 453
451 bayesStruct.updateBestEstimate(); 468 bayesStruct.updateBestEstimate();
452 469
453 } 470 }
454 471
455 472
456 void midiEventHolder::drawFile(){ 473 void midiEventHolder::drawMidiFile(){
474
457 //draws midi file on scrolling screen 475 //draws midi file on scrolling screen
458 int size = recordedNoteOnMatrix.size(); 476 int size = recordedNoteOnMatrix.size();
459 if (size > 0){ 477 if (size > 0){
460 478
461 numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in 479 numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in
462 480
463 // numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down 481 // numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down
464 timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen); 482 timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen);
465 483
466 while (noteArrayIndex < recordedNoteOnMatrix.size() && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] ) 484 while (noteArrayIndex < recordedNoteOnMatrix.size() && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] )
467 noteArrayIndex++; 485 noteArrayIndex++;
468 486
483 for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)recordedNoteOnMatrix.size());tmpIndex++){ 501 for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)recordedNoteOnMatrix.size());tmpIndex++){
484 502
485 if (checkIfMatchedNote(tmpIndex)) 503 if (checkIfMatchedNote(tmpIndex))
486 ofSetColor(0,0,255); 504 ofSetColor(0,0,255);
487 else if(noteOnMatches[tmpIndex]){ 505 else if(noteOnMatches[tmpIndex]){
488 ofSetColor(255,0,255); 506 ofSetColor(255,0,255);
489 }else{ 507 }else{
490 ofSetColor(255,255,255); 508 ofSetColor(255,255,255);
491 } 509 }
492 510
493 511
494 512
495 // XXX replace ofgetwidth below 513 // XXX replace ofgetwidth below
496 //if (tmpIndex >= 0 && tmpIndex < size) 514 //if (tmpIndex >= 0 && tmpIndex < size)
497 int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen; 515 int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen;
498 int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen; 516 int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen;
499 517
500 518
503 521
504 } 522 }
505 523
506 524
507 int xLocation;// = getLocationFromTicks(tickLocation); 525 int xLocation;// = getLocationFromTicks(tickLocation);
508 // ofLine(xLocation, 0, xLocation, (*screenHeight)); 526 // ofLine(xLocation, 0, xLocation, (*screenHeight));
509 527
510 //orange line at best estimate 528 //orange line at best estimate
511 xLocation = getLocationFromMillis(bayesStruct.bestEstimate); 529 xLocation = getLocationFromMillis(bayesStruct.bestEstimate);
512 ofSetColor(250,100,0); 530 ofSetColor(250,100,0);
513 ofLine(xLocation, 0, xLocation, (*screenHeight)); 531 ofLine(xLocation, 0, xLocation, (*screenHeight));
521 ofSetColor(0,100,255); 539 ofSetColor(0,100,255);
522 xLocation = getLocationFromMillis(windowStartTime); 540 xLocation = getLocationFromMillis(windowStartTime);
523 ofLine(xLocation, 0, xLocation, (*screenHeight)); 541 ofLine(xLocation, 0, xLocation, (*screenHeight));
524 xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth); 542 xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth);
525 ofLine(xLocation, 0, xLocation, (*screenHeight)); 543 ofLine(xLocation, 0, xLocation, (*screenHeight));
526 544
527 545
528 } 546 }
529 547
530
531
532 ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); 548 ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
533 549
534 ofDrawBitmapString(timeString, 20, 60); 550 ofDrawBitmapString(timeString, 20, 60);
551
552
553 }
554
555 void midiEventHolder::drawFile(){
556 drawMidiFile();
557
535 558
536 // bayesStruct.drawArrays(); 559 // bayesStruct.drawArrays();
537 560
538 // ofSetColor(200,200,0); 561 // ofSetColor(200,200,0);
539 // bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800); 562 // bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800);
540 563
541 //need to draw arrays within correct timescope 564 //need to draw arrays within correct timescope
565 if (drawPhaseMode)
542 bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); 566 bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen));
543 567
544 if (drawTempoMode) 568 if (drawTempoMode)
545 bayesStruct.drawTempoArrays(); 569 bayesStruct.drawTempoArrays();
546 570