Mercurial > hg > midi-score-follower
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:b299a65a3ad0 | 1:1a32ce016bb9 |
---|---|
23 pulsesPerQuarternote = 240; | 23 pulsesPerQuarternote = 240; |
24 noteArrayIndex = 0; | 24 noteArrayIndex = 0; |
25 noteMinimum = 30; | 25 noteMinimum = 30; |
26 noteMaximum = 96; | 26 noteMaximum = 96; |
27 | 27 |
28 minimumMatchSpeed = 0.5; | 28 minimumMatchSpeed = 0.7; |
29 maximumMatchSpeed = 2.0; | 29 maximumMatchSpeed = 1.3; |
30 likelihoodWidth = 100; | 30 likelihoodWidth = 100; |
31 likelihoodToNoiseRatio = 50; | 31 likelihoodToNoiseRatio = 50; |
32 | 32 |
33 matchWindowWidth = 6000;//window size for matching in ms | 33 matchWindowWidth = 4000;//window size for matching in ms |
34 | 34 |
35 bayesStruct.resetSize(4000); | 35 bayesStruct.resetSize(matchWindowWidth); |
36 bayesStruct.resetSpeedSize(200); | 36 bayesStruct.resetSpeedSize(200); |
37 bayesStruct.setRelativeSpeedScalar(0.01); | 37 bayesStruct.setRelativeSpeedScalar(0.01); |
38 bayesStruct.relativeSpeedPrior.getMaximum(); | 38 bayesStruct.relativeSpeedPrior.getMaximum(); |
39 bayesStruct.simpleExample(); | 39 bayesStruct.simpleExample(); |
40 | 40 |
59 | 59 |
60 bayesStruct.resetSpeedToOne(); | 60 bayesStruct.resetSpeedToOne(); |
61 | 61 |
62 } | 62 } |
63 | 63 |
64 void midiEventHolder::clearAllEvents(){ | |
65 recordedNoteOnMatrix.clear(); | |
66 matchesFound.clear(); | |
67 noteOnMatches.clear(); | |
68 recordedEventTimes.clear(); | |
69 | |
70 //played events: | |
71 playedEventTimes.clear(); | |
72 playedNoteOnMatrix.clear(); | |
73 matchMatrix.clear(); | |
74 } | |
75 | |
64 void midiEventHolder::printNotes(){ | 76 void midiEventHolder::printNotes(){ |
65 printf("RECORDED MATRIX"); | 77 printf("RECORDED MATRIX"); |
66 for (int i = 0;i < recordedNoteOnMatrix.size();i++){ | 78 for (int i = 0;i < recordedNoteOnMatrix.size();i++){ |
67 printf("%i :: %i @ %f\n", recordedNoteOnMatrix[i][0], recordedNoteOnMatrix[i][1], recordedEventTimes[i]); | 79 printf("%i :: %i @ %f\n", recordedNoteOnMatrix[i][0], recordedNoteOnMatrix[i][1], recordedEventTimes[i]); |
68 } | 80 } |
149 //trying to switch to prior | 161 //trying to switch to prior |
150 | 162 |
151 bayesStruct.lastEventTime = ofGetElapsedTimeMillis(); | 163 bayesStruct.lastEventTime = ofGetElapsedTimeMillis(); |
152 | 164 |
153 //do the cross update to find current posterior for location | 165 //do the cross update to find current posterior for location |
166 // totalConfidence= 0; | |
154 int numberOfMatchesFound = findLocalMatches(pitch); | 167 int numberOfMatchesFound = findLocalMatches(pitch); |
155 setMatchLikelihoods(numberOfMatchesFound); | 168 setMatchLikelihoods(numberOfMatchesFound); |
156 bayesStruct.calculatePosterior(); | 169 bayesStruct.calculatePosterior(); |
157 | 170 |
158 //having found matches we have matches for new note and matches for previous notes | 171 //having found matches we have matches for new note and matches for previous notes |
164 | 177 |
165 int midiEventHolder::findLocalMatches(int notePitch){ | 178 int midiEventHolder::findLocalMatches(int notePitch){ |
166 | 179 |
167 //here we find the matches to the new note within appropriate range | 180 //here we find the matches to the new note within appropriate range |
168 | 181 |
169 matchString += ", "+ofToString(notePitch); | 182 matchString = ""; |
170 | 183 |
171 windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis | 184 windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis |
172 int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth); | 185 int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth); |
186 | |
187 matchString += " pitch: "+ofToString(notePitch)+" matches "+ofToString(numberOfMatches)+" win start "+ofToString(windowStartTime); | |
173 | 188 |
174 return numberOfMatches; | 189 return numberOfMatches; |
175 | 190 |
176 | 191 |
177 } | 192 } |
186 | 201 |
187 for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){ | 202 for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){ |
188 // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset); | 203 // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset); |
189 //this is the vent time since start of file | 204 //this is the vent time since start of file |
190 if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){ | 205 if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){ |
191 bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, 0.5 * likelihoodToNoiseRatio); | 206 // double confidenceMeasure = 0; |
207 // if (totalConfidence > 0) | |
208 // confidenceMeasure = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[matchesFound[i]])/totalConfidence; | |
209 | |
210 bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, 0.5 * likelihoodToNoiseRatio );//* confidenceMeasure | |
192 }//end if | 211 }//end if |
193 } | 212 } |
194 bayesStruct.likelihood.addConstant(0.01); | 213 bayesStruct.likelihood.addConstant(0.01); |
195 } | 214 } |
196 | 215 |
209 | 228 |
210 | 229 |
211 while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < endTime){ | 230 while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < endTime){ |
212 if (recordedNoteOnMatrix[startIndex][1] == notePitch){ | 231 if (recordedNoteOnMatrix[startIndex][1] == notePitch){ |
213 matchesFound.push_back(startIndex); | 232 matchesFound.push_back(startIndex); |
233 double confidence = bayesStruct.posterior.getValueAtMillis(mouseX); | |
234 // recordedEventTimes[startIndex]); | |
235 matchString += "["+ofToString(startIndex)+"] = "+ofToString(confidence, 3)+" ."; | |
214 } | 236 } |
215 startIndex++; | 237 startIndex++; |
216 } | 238 } |
217 | 239 |
218 // printf("%i MATCHES TO Note %i found\n", (int)matchesFound.size(), notePitch); | 240 // printf("%i MATCHES TO Note %i found\n", (int)matchesFound.size(), notePitch); |
257 double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; | 279 double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; |
258 | 280 |
259 for (int k = 0;k < matchMatrix[previousIndex][0];k++){ | 281 for (int k = 0;k < matchMatrix[previousIndex][0];k++){ |
260 int recordedPreviousIndex = matchMatrix[previousIndex][k+1]; | 282 int recordedPreviousIndex = matchMatrix[previousIndex][k+1]; |
261 | 283 |
262 // printf("(%i)", matchMatrix[currentPlayedIndex][i+1]); | 284 |
263 // printf("[%i] :: ", recordedPreviousIndex); | |
264 | 285 |
265 double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex]; | 286 double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex]; |
266 /// printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); | 287 |
267 | 288 |
268 //we want the speed of the recording relative to that of the playing live | 289 //we want the speed of the recording relative to that of the playing live |
269 | 290 |
270 double speedRatio = recordedTimeDifference / playedTimeDifference; | 291 double speedRatio = recordedTimeDifference / playedTimeDifference; |
271 if (speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){ | 292 if (speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){ |
272 | 293 printf("(%i)", matchMatrix[currentPlayedIndex][i+1]); |
273 // printf("update on speed ratio %f", speedRatio); | 294 printf("[%i] :: ", recordedPreviousIndex); |
295 printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); | |
296 printf("update on speed ratio %f\n", speedRatio); | |
297 // matchString += " speed: "+ofToString(speedRatio, 3); | |
274 // commented for debug | 298 // commented for debug |
275 bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match | 299 bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match |
276 | 300 |
277 } | 301 } |
278 // printf("\n"); | 302 // printf("\n"); |
368 ofLine(xLocation, 0, xLocation, (*screenHeight)); | 392 ofLine(xLocation, 0, xLocation, (*screenHeight)); |
369 | 393 |
370 | 394 |
371 } | 395 } |
372 | 396 |
397 | |
398 | |
373 ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); | 399 ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); |
374 | 400 |
375 ofDrawBitmapString(timeString, 20, 60); | 401 ofDrawBitmapString(timeString, 20, 60); |
376 | 402 |
377 // bayesStruct.drawArrays(); | 403 // bayesStruct.drawArrays(); |
380 // bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800); | 406 // bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800); |
381 | 407 |
382 //need to draw arrays within correct timescope | 408 //need to draw arrays within correct timescope |
383 bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); | 409 bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); |
384 | 410 |
385 //bayesStruct.drawTempoArrays(); | 411 if (drawTempoMode) |
386 | 412 bayesStruct.drawTempoArrays(); |
413 | |
414 | |
415 ofSetColor(0, 0, 0); | |
387 ofDrawBitmapString(matchString, 20, ofGetHeight() - 20); | 416 ofDrawBitmapString(matchString, 20, ofGetHeight() - 20); |
388 | 417 |
418 double confidence = bayesStruct.posterior.getValueAtMillis(mouseX); | |
419 string mouseString = "mouseX "+ofToString(confidence, 3)+" ."; | |
420 ofDrawBitmapString(mouseString, 20 , ofGetHeight() - 40); | |
389 } | 421 } |
390 | 422 |
391 int midiEventHolder::getLocationFromTicks(double tickPosition){ | 423 int midiEventHolder::getLocationFromTicks(double tickPosition){ |
392 return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen); | 424 return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen); |
393 } | 425 } |