comparison jnmr/midiEventHolder.cpp @ 46:43edc8abe2a7

Fixed bug in complex update due to mismatch between ms and vector units
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sun, 05 Feb 2012 19:40:21 +0000
parents 6c8a048720c3
children 1726189a6317
comparison
equal deleted inserted replaced
45:90ad1817ca56 46:43edc8abe2a7
8 */ 8 */
9 9
10 10
11 //Main file to look at here is newNoteEvent() - this calls everything else to update the Bayesian array 11 //Main file to look at here is newNoteEvent() - this calls everything else to update the Bayesian array
12 12
13 //Relative speed is RECORDED / PLAYED
14 //so for timedifference t
15 //this is t/scalar in terms of position units of played time
16 //and by relative speed r, r*t/scalar
17
18
13 #include "midiEventHolder.h" 19 #include "midiEventHolder.h"
14 20
15 #include <iostream> 21 #include <iostream>
16 #include <fstream> 22 #include <fstream>
17 #include <assert.h> 23 #include <assert.h>
18 24
19 midiEventHolder::midiEventHolder(){ 25 midiEventHolder::midiEventHolder(){
20 26
21 27
28 double scalarForPositionVectors = 20;
22 29
23 // recordedNoteOnIndex = 0; 30 // recordedNoteOnIndex = 0;
24 alignmentPosition = 0; 31 alignmentPosition = 0;
25 32
26 useTempoPrior = false;//puts sine wave round tempo 33 useTempoPrior = false;//puts sine wave round tempo
66 73
67 74
68 75
69 speedPriorValue = 1.0; 76 speedPriorValue = 1.0;
70 77
71 78 int tmpArraySize = (int)(matchWindowWidth/scalarForPositionVectors);
72 bayesStruct.resetSize(matchWindowWidth); 79 bayesStruct.resetSize(tmpArraySize);
73 bayesStruct.setPositionDistributionScalar(1); 80 bayesStruct.setPositionDistributionScalar(scalarForPositionVectors);
81 printf("ARRAY SIZE IS %i\n", tmpArraySize);
74 82
75 bayesStruct.resetSpeedSize(200); 83 bayesStruct.resetSpeedSize(200);
76 bayesStruct.setRelativeSpeedScalar(0.01); 84 bayesStruct.setRelativeSpeedScalar(0.01);
77 bayesStruct.relativeSpeedPrior.getMaximum(); 85 bayesStruct.relativeSpeedPrior.getMaximum();
78 //bayesStruct.simpleExample(); 86 //bayesStruct.simpleExample();
127 // relativeSpeedForSmooth = 1.0; 135 // relativeSpeedForSmooth = 1.0;
128 // storedSmoothPlayPosition = smoothPlayPosition; 136 // storedSmoothPlayPosition = smoothPlayPosition;
129 // lastSmoothUpdateTime = getTimeNow(0); 137 // lastSmoothUpdateTime = getTimeNow(0);
130 138
131 printf("reset speed prior is %f\n", speedPriorValue); 139 printf("reset speed prior is %f\n", speedPriorValue);
132 bayesStruct.resetSpeedToOne(); 140 // bayesStruct.resetSpeedToOne();
133 bayesStruct.setSpeedPrior(speedPriorValue); 141 bayesStruct.setSpeedPrior(speedPriorValue);
134 setMatchedNotesBackToFalse(); 142 setMatchedNotesBackToFalse();
135 143
136 periodCounter = 0; 144 // periodCounter = 0;
137 for (int i = 0;i < periodValues.size();i++){ 145 // for (int i = 0;i < periodValues.size();i++){
138 // printf("period at %f is %f\n", periodValues[i][2], periodValues[i][1]); 146 // printf("period at %f is %f\n", periodValues[i][2], periodValues[i][1]);
139 } 147 // }
140 /* if (periodValues.size() > 0){ 148 /* if (periodValues.size() > 0){
141 updatePeriodValue(0);// periodValues[0][2]; 149 updatePeriodValue(0);// periodValues[0][2];
142 printf("Resetting period to %f , size is %i\n", period, (int)periodValues.size()); 150 printf("Resetting period to %f , size is %i\n", period, (int)periodValues.size());
143 } 151 }
144 */ 152 */
187 return (period * ticks / (double) pulsesPerQuarternote); 195 return (period * ticks / (double) pulsesPerQuarternote);
188 } 196 }
189 197
190 void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){ 198 void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){
191 // tempoSpeedString = ""; 199 // tempoSpeedString = "";
192 200
193 //MOVE INTO BAYESSTRUCT?? XXX 201 //MOVE INTO BAYESSTRUCT?? XXX
194 //bayesStruct.copyPriorToPosterior(); 202 //bayesStruct.copyPriorToPosterior();
195 //why was this here?? 203 //why was this here??
196 bayesStruct.prior.copyFromDynamicVector(bayesStruct.posterior);//try the otehr way 204 bayesStruct.prior.copyFromDynamicVector(bayesStruct.posterior);//try the otehr way
197 //bayesStruct.copyPriorToPosterior(); 205 //bayesStruct.copyPriorToPosterior();
250 // timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0); 258 // timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0);
251 259
252 //then we recalculate the window start based on MAP being central 260 //then we recalculate the window start based on MAP being central
253 //then we do the matches on these and the likelihood on these. 261 //then we do the matches on these and the likelihood on these.
254 262
255 bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2))); 263 bayesStruct.setNewDistributionOffsets(max(bayesStruct.posterior.offset, bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)));
256 // bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)); 264 //bayesStruct.setNewDistributionOffsets(max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
257 265
258 timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0); 266 timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0);
259 timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1); 267 timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1);
260 timeString += " error "+ofToString(minimumMatchError, 0); 268 timeString += " error "+ofToString(minimumMatchError, 0);
261 timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 1); 269 timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 1);
269 277
270 timeString += " new OFF "+ofToString(bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2), 1); 278 timeString += " new OFF "+ofToString(bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2), 1);
271 timeString += " notearrayindex "+ofToString(noteArrayIndex, 0); 279 timeString += " notearrayindex "+ofToString(noteArrayIndex, 0);
272 //when this is off teh screen there is a problem somehow XXX 280 //when this is off teh screen there is a problem somehow XXX
273 281
274 bayesStruct.posterior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));// bayesStruct.prior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)); 282 bayesStruct.posterior.offset = bayesStruct.prior.offset;
283 //max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));// bayesStruct.prior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));
275 284
276 //trying to switch to prior 285 //trying to switch to prior
277 286
278 287
279 bayesStruct.lastEventTime = timePlayed;//bayesStruct.lastEventTime = ofGetElapsedTimeMillis(); 288 bayesStruct.lastEventTime = timePlayed;//bayesStruct.lastEventTime = ofGetElapsedTimeMillis();
287 if (recordedEventTimes.size() > 0){ 296 if (recordedEventTimes.size() > 0){
288 updateTempo(); 297 updateTempo();
289 //calcuateNewInterNoteIntervals(); 298 //calcuateNewInterNoteIntervals();
290 } 299 }
291 300
301
292 //storedSmoothPlayPosition = smoothPlayPosition; 302 //storedSmoothPlayPosition = smoothPlayPosition;
293 303
294 } 304 }
295 305
296 void midiEventHolder::updateTempo(){ 306 void midiEventHolder::updateTempo(){
340 double quantity = likelihoodToNoiseRatio / numberOfMatches; 350 double quantity = likelihoodToNoiseRatio / numberOfMatches;
341 351
342 for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){ 352 for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){
343 // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset); 353 // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset);
344 //this is the vent time since start of file 354 //this is the vent time since start of file
345 if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){ 355 if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize*bayesStruct.likelihood.scalar){
346 // double confidenceMeasure = 0; 356 // double confidenceMeasure = 0;
347 // if (totalConfidence > 0) 357 // if (totalConfidence > 0)
348 // confidenceMeasure = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[matchesFound[i]])/totalConfidence; 358 // confidenceMeasure = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[matchesFound[i]])/totalConfidence;
349 359
350 //bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, quantity);//* confidenceMeasure 360 //bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, quantity);//* confidenceMeasure
676 686
677 687
678 if (recordedTimeDifference > minimumTimeIntervalForTempoUpdate 688 if (recordedTimeDifference > minimumTimeIntervalForTempoUpdate
679 && speedRatio < maximumMatchSpeed && speedRatio > minimumMatchSpeed){ 689 && speedRatio < maximumMatchSpeed && speedRatio > minimumMatchSpeed){
680 690
681 /* printf("(%i)", previousIndex); 691 /* printf("(%i)", previousIndex);
682 printf("[%i] :: ", recordedPreviousIndex); 692 printf("[%i] :: ", recordedPreviousIndex);
683 // printf(" conf %f & %f ", currentMatchConfidence, previousMatchConfidence); 693 // printf(" conf %f & %f ", currentMatchConfidence, previousMatchConfidence);
684 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); 694 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference);
685 printf("update on speed ratio %f\n", speedRatio); 695 printf("update on speed ratio %f\n", speedRatio);
686 */ 696 */
687 // matchString += " speed: "+ofToString(speedRatio, 3); 697 // matchString += " speed: "+ofToString(speedRatio, 3);
688 // commented for debug 698 // commented for debug
689 699
690 700
691 double priorWeighting = 1; 701 double priorWeighting = 1;
718 } 728 }
719 729
720 730
721 if (needToUpdate) 731 if (needToUpdate)
722 bayesStruct.updateTempoDistribution(); 732 bayesStruct.updateTempoDistribution();
733
723 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); 734 //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
724 } 735 }
725 736
726 737
727 void midiEventHolder::calcuateNewInterNoteIntervals(){ 738 void midiEventHolder::calcuateNewInterNoteIntervals(){
876 887
877 smoothPlayPosition = newPosition; 888 smoothPlayPosition = newPosition;
878 889
879 } 890 }
880 891
881 892 /*
882 void midiEventHolder::updatePeriodValue(const double& millis){ 893 void midiEventHolder::updatePeriodValue(const double& millis){
883 894
884 double tmp = period; 895 double tmp = period;
885 /* 896
886 while (periodCounter >= 0 && periodCounter < periodValues.size()-1 && periodValues[periodCounter][2] < millis){ 897 // while (periodCounter >= 0 && periodCounter < periodValues.size()-1 && periodValues[periodCounter][2] < millis){
887 periodCounter++; 898 // periodCounter++;
888 } 899 // }
889 while (periodCounter > 0 && periodValues[periodCounter][2] > millis){ 900 // while (periodCounter > 0 && periodValues[periodCounter][2] > millis){
890 periodCounter--; 901 // periodCounter--;
891 } 902 // }
892 */ 903 //
893 //period = periodValues[periodCounter][1]; 904 //period = periodValues[periodCounter][1];
894 905
895 if (period != tmp){ 906 if (period != tmp){
896 printf("new period at %f of %f\n", millis, period); 907 printf("new period at %f of %f\n", millis, period);
897 } 908 }
898 } 909 }
910 */
899 911
900 void midiEventHolder::updateNoteCounter(){ 912 void midiEventHolder::updateNoteCounter(){
901 while (totalNoteCounterIndex < bestMatchIndex){ 913 while (totalNoteCounterIndex < bestMatchIndex){
902 int tmpPitch = recordedNoteOnMatrix[totalNoteCounterIndex][1]; 914 int tmpPitch = recordedNoteOnMatrix[totalNoteCounterIndex][1];
903 recordedTotalNoteCounterByPitch[tmpPitch] += 1; 915 recordedTotalNoteCounterByPitch[tmpPitch] += 1;
905 } 917 }
906 } 918 }
907 919
908 920
909 void midiEventHolder::drawMidiFile(){ 921 void midiEventHolder::drawMidiFile(){
922 //ofBackground(80,80,80);
910 923
911 //draws midi file on scrolling screen 924 //draws midi file on scrolling screen
912 int size = recordedNoteOnMatrix.size(); 925 int size = recordedNoteOnMatrix.size();
913 if (size > 0){ 926 if (size > 0){
914 927
1001 ofDrawBitmapString(indexString, 20, 40); 1014 ofDrawBitmapString(indexString, 20, 40);
1002 */ 1015 */
1003 } 1016 }
1004 1017
1005 //ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); 1018 //ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
1006 1019 ofSetColor(255,255,255);
1007 //ofDrawBitmapString(timeString, 20, 60); 1020 ofDrawBitmapString(timeString, 20, 60);
1008 1021
1009 //last played piutch 1022 //last played piutch
1010 ofSetColor(0,200,0,50); 1023 ofSetColor(0,200,0,50);
1011 int yLocation = (*screenHeight) - ((lastPlayedPitch - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum)); 1024 int yLocation = (*screenHeight) - ((lastPlayedPitch - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum));
1012 ofRect(0,yLocation, 100, noteHeight); 1025 ofRect(0,yLocation, 100, noteHeight);
1139 printf("\n"); 1152 printf("\n");
1140 } 1153 }
1141 1154
1142 } 1155 }
1143 1156
1144 int midiEventHolder::getLocationFromTicks(double tickPosition){ 1157 //int midiEventHolder::getLocationFromTicks(double tickPosition){
1145 return 0; 1158 // return 0;
1146 // return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen); 1159 // return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen);
1147 //not used 1160 //not used
1148 } 1161 //}
1149 1162
1150 int midiEventHolder::getLocationFromMillis(double millisPosition){ 1163 int midiEventHolder::getLocationFromMillis(double millisPosition){
1151 //(getEventTimeTicks(windowStartTime+matchWindowWidth) - numberOfScreensIn*ticksPerScreen)*(*screenWidth) / (double)ticksPerScreen 1164 //(getEventTimeTicks(windowStartTime+matchWindowWidth) - numberOfScreensIn*ticksPerScreen)*(*screenWidth) / (double)ticksPerScreen
1152 return (millisPosition - timeOffsetForScreen)*(*screenWidth)/getEventTimeMillis(ticksPerScreen); 1165 return (millisPosition - timeOffsetForScreen)*(*screenWidth)/getEventTimeMillis(ticksPerScreen);
1153 } 1166 }
1154 1167
1155 1168 /*
1156 void midiEventHolder::exampleCrossUpdate(){ 1169 void midiEventHolder::exampleCrossUpdate(){
1157 1170
1158 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, 200); 1171 bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, 200);
1159 1172
1160 } 1173 }
1161 1174 */
1162 1175
1163 void midiEventHolder::setStartPlayingTimes(){ 1176 void midiEventHolder::setStartPlayingTimes(){
1164 startPlayingTime = getTimeNow(0);//ofGetElapsedTimeMillis(); 1177 startPlayingTime = getTimeNow(0);//ofGetElapsedTimeMillis();
1165 //startTime = startPlayingTime; 1178 //startTime = startPlayingTime;
1166 printf("starting playing at time %f\n", startPlayingTime); 1179 printf("starting playing at time %f\n", startPlayingTime);