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 }