changeset 50:158f5f38e9d3

outputting exact difference for annotations, comparison with match annotations is now working over all rwc files
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Thu, 29 Mar 2012 13:41:59 +0100
parents 3ce6dadd8167
children ef30f465a904
files jnmr/Annotations.cpp jnmr/BayesianArrayStructure.cpp jnmr/BayesianArrayStructure.h jnmr/midiEventHolder.cpp jnmr/midiEventHolder.h jnmr/testApp.cpp matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp matchAnnotationSrc/matchAnnotations.cpp matchAnnotationSrc/testApp.cpp matchAnnotationSrc/testApp.h
diffstat 10 files changed, 314 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/jnmr/Annotations.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/Annotations.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -18,7 +18,7 @@
 // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv"
 	rwcAnnotations.clear();
 	
-	printf("ANNOTATIONS : READ FILE %s\n", pathName.c_str());
+//	printf("ANNOTATIONS : READ FILE %s\n", pathName.c_str());
 	ifstream file ( pathName.c_str()); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/
 	string value, tmpLine;
 	stringstream iss;
--- a/jnmr/BayesianArrayStructure.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/BayesianArrayStructure.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -14,7 +14,9 @@
 
 BayesianArrayStructure::BayesianArrayStructure(){
 	printf("Bayesian structure: DeFault constructor called\n");
-	usingIntegratedTempoEstimate = true;// use max index
+	usingIntegratedTempoEstimate = false;// use max index
+	
+	useConstantTempoDistribution = false;
 	
 	relativeSpeedLikelihoodStdDev = 5.0;
 	
@@ -173,6 +175,7 @@
 	posterior.getMaximum();
 	bestEstimate = posterior.getRealTermsAsIndex(0);
 	
+	
 	printf("bayes reset arrays - best estimate time %f\n", lastBestEstimateUpdateTime);
 	
 	setSpeedPrior(speedPriorValue);
@@ -459,6 +462,13 @@
 	relativeSpeedPosterior.updateLimitedIntegratedEstimate();
 	
 	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
+	
+	if (useConstantTempoDistribution){
+	//tmp try constant tempo
+	relativeSpeedPosterior.zero();
+	relativeSpeedPosterior.addConstant(1);
+	relativeSpeedPosterior.renormalise();
+	}
 }
 
 
--- a/jnmr/BayesianArrayStructure.h	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/BayesianArrayStructure.h	Thu Mar 29 13:41:59 2012 +0100
@@ -95,6 +95,6 @@
 	bool* realTimeMode;
 	bool usingIntegratedTempoEstimate;
 	double relativeSpeedLikelihoodStdDev;
-
+	bool useConstantTempoDistribution;
 };
 #endif
--- a/jnmr/midiEventHolder.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/midiEventHolder.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -35,7 +35,7 @@
 	confidenceWeightingUsed = true;
 	newOptimalMethod = true;
 	
-	matchWindowWidth = 16000;//window size for matching in ms 
+	matchWindowWidth = 20000;//window size for matching in ms 
 	interNoteRange = 1600;//preferred duration
 	//so max here is really four
 	
@@ -44,7 +44,7 @@
 	likelihoodToNoiseRatio = 0.20;//was 0.02 on 18/11/11, changing to give more weight to observations
 									//was 0.08 on 11/12/11 but need more for tempo varn in rwc database
 	
-	bayesStruct.speedLikelihoodNoise = 0.1;//was 0.05
+	bayesStruct.speedLikelihoodNoise = 0.2;//changed from 0.1, was 0.05
 	bayesStruct.speedDecayWidth = 40;
 	bayesStruct.speedDecayAmount = 10;
 	
@@ -131,7 +131,7 @@
 
 	interNoteIntervals.clear();
 	
-	smoothIndex = 0;
+	outputIndex = 0;
 	smoothPlayPosition = 0.0;
 	causalPlayPosition = 0;
 	lastCausalUpdateTime = getTimeNow(0);
@@ -157,6 +157,21 @@
 	//period = 500.0;
 }
 
+void midiEventHolder::testSpeedPriorSetting(){
+	if (speedPriorValue > 2){
+		bayesStruct.resetSpeedSize(speedPriorValue * 200);
+		bayesStruct.setRelativeSpeedScalar(0.01);
+		bayesStruct.relativeSpeedPrior.getMaximum();
+		printf("SPEED SIZE EXCEEDS MAXIMUM!!! RESETTING TO SIXE %i\n", (int)(speedPriorValue * 200));
+	}
+	else{
+		bayesStruct.resetSpeedSize(200);
+		bayesStruct.setRelativeSpeedScalar(0.01);
+		bayesStruct.relativeSpeedPrior.getMaximum();
+	}
+
+}
+
 void midiEventHolder::setMatchedNotesBackToFalse(){
 	for (int i = 0;i < noteOnMatches.size();i++)
 		noteOnMatches[i] = false;
@@ -309,14 +324,13 @@
 
 void midiEventHolder::updateTempo(){
 	//having found matches we have matches for new note and matches for previous notes
-	if (newOptimalMethod)
+	if (newOptimalMethod)//now true
 		findOptimumTempoPairsToCurrentBestMatch();
 	else if (!confidenceWeightingUsed)
 		findLocalTempoPairs();
 	else
 		findLocalTempoPairsWeightedForConfidence();
 	
-	
 	//bayesStruct.addGaussianNoiseToSpeedPosterior(10);
 }
 
@@ -376,6 +390,7 @@
 	if (recordedEventTimes.size() > 0){
 	
 		//get to the right range of events to check in
+		//OPTIMIZE!
 		while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < startTime)
 			startIndex++;
 		   
@@ -396,7 +411,7 @@
 			double eventConfidence = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[startIndex]);
 				if (eventConfidence > minimumConfidence){
 					minimumConfidence = eventConfidence;
-					bestMatchIndex = startIndex;
+					bestMatchIndex = startIndex;//could change this to minimumMatchError below
 				}
 			d.push_back(eventConfidence);
 			
@@ -408,6 +423,7 @@
 				//record the error between expected and observed times
 				tmpError = abs(recordedEventTimes[startIndex] - bayesStruct.bestEstimate);
 				minimumMatchError = tmpError;//recordedEventTimes[startIndex] - bayesStruct.bestEstimate;
+			//	bestMatchIndex = startIndex;
 			}
 			
 		}
@@ -794,15 +810,22 @@
 	//did just update smooth to current if it was less
 	
 	if (smoothPlayPosition < bayesStruct.bestEstimate){
-		updateSmoothPositionTo(bayesStruct.bestEstimate);
-		//smoothPlayPosition = bayesStruct.bestEstimate;
+	//	updateOutputPositionTo(bayesStruct.bestEstimate);
+		smoothPlayPosition = bayesStruct.bestEstimate;
 	}
 	
+	updateOutputPositionTo(causalPlayPosition);	//need it outputting before the update
+	
+	updateCausalPlayPosition(getTimeNow(bayesStruct.lastBestEstimateUpdateTime));
+
 
 	
-	updateCausalPlayPosition(getTimeNow(bayesStruct.lastBestEstimateUpdateTime));
+	//can choose to output either the smooth position (i.e. forwards)
+	//or causal play position which aims toward our current smooth position in near future
 	
-/*
+	
+
+	/*
 	//now we try updating it to a causal path that tries to match into the future	
  if (smoothPlayPosition < causalPlayPosition){
 		updateSmoothPositionTo(causalPlayPosition);
@@ -822,101 +845,134 @@
 	
 }
 
-void midiEventHolder::updateSmoothPositionTo(const double& newPosition){
+void midiEventHolder::updateOutputPositionTo(const double& newPosition){
 	//smooth play position was where we last outputted notes from.
 	//checking index is there to make sense.
-	while (smoothIndex > 0 && recordedEventTimes[smoothIndex] > smoothPlayPosition){
-		smoothIndex--;
-		//printf("going backewaers on smooth, ");
+//	double checkPosition = smoothPlayPosition;
+	double checkPosition = lastUpdatePosition;
+	
+	
+	while (outputIndex > 0 && recordedEventTimes[outputIndex] > checkPosition){
+		outputIndex--;
+//		printf("going backewards, smooth time %f, ", recordedEventTimes[outputIndex]);
 	}
-	while (smoothIndex < recordedEventTimes.size()-1 && recordedEventTimes[smoothIndex] < smoothPlayPosition){
-		smoothIndex++;
-		//printf("outputting  smooth\n ");
+	while (outputIndex < recordedEventTimes.size()-1 && recordedEventTimes[outputIndex] < checkPosition){
+		outputIndex++;
+//		printf("outputting smooth forwards time %f\n ", recordedEventTimes[outputIndex], checkPosition);
 	}
 	
+//	printf("last output position %f, new position %f\n", checkPosition, newPosition);	
+//	printf("causal pos %.0f, smooth pos %.0f, best est %.0f\n", causalPlayPosition, smoothPlayPosition, bayesStruct.bestEstimate);
+	
+	outputPosition = recordedEventTimes[outputIndex];
 
 	double playingTime = ofGetElapsedTimeMillis();
 	playingTime -= startPlayingTime;
 	//now at the last one
 	
-	float smoothLocation = beatPositions[smoothIndex];
-	int currentNote = recordedNoteOnMatrix[smoothIndex][1];
+	float smoothLocation = beatPositions[outputIndex];
+	int currentNote = recordedNoteOnMatrix[outputIndex][1];
 	
-	while (smoothIndex < recordedEventTimes.size() && recordedEventTimes[smoothIndex] < newPosition){
+	while (outputIndex < recordedEventTimes.size() && recordedEventTimes[outputIndex] < newPosition){
 		float annotationTime = 0;
 		float annotationLocation = 0;
 		int annotationTick = 0;
 		int annotationNote = 0;
 		float difference = 10000;//very big
-		float currentLocationDifference = 1.0;
+		//float currentLocationDifference = 1.0;
+		
+		double amountSinceLastUpdate = 0.0;//between 0 and 1, the exact position of this event since last update
+			if (newPosition  > lastUpdatePosition){
+				amountSinceLastUpdate = (recordedEventTimes[outputIndex] - lastUpdatePosition)/(newPosition - lastUpdatePosition);
+			}
+		
 		float range = 1.0;
-		if (smoothIndex < myNotation.rwcAnnotations.size()){
+		if (outputIndex < myNotation.rwcAnnotations.size()){
 			//add in test here to find closest matching note
 			
 		
-			annotationTime = myNotation.rwcAnnotations[smoothIndex].eventTime;
-			annotationNote = myNotation.rwcAnnotations[smoothIndex].midiNote;
-			annotationLocation = myNotation.rwcAnnotations[smoothIndex].beatLocation;
+			annotationTime = myNotation.rwcAnnotations[outputIndex].eventTime;
+			annotationNote = myNotation.rwcAnnotations[outputIndex].midiNote;
+			annotationLocation = myNotation.rwcAnnotations[outputIndex].beatLocation;
 			annotationTick = round(annotationLocation*480.0);
 		}else{
 			printf("No annotaion size %i\n", (int)myNotation.rwcAnnotations.size());
 		}
 		
+		double exactPlayingTime = amountSinceLastUpdate*playingTime + ((1 - amountSinceLastUpdate)*lastUpdatePlayingTime);
 		difference = playingTime - (annotationTime*1000.0);
-		
-		if ((*fileOutput).is_open()){
-			(*fileOutput) << fixed << beatPositions[smoothIndex] <<",\t" <<  recordedNoteOnMatrix[smoothIndex][1] << ",\t";
+		double exactDifference = exactPlayingTime - (annotationTime*1000.0);
+	/*
+	 //NO LONGER NEEDED ALLO
+	 if ((*fileOutput).is_open()){
+			(*fileOutput) << fixed << beatPositions[outputIndex] <<",\t" <<  recordedNoteOnMatrix[outputIndex][1] << ",\t";
 			(*fileOutput) << playingTime ;
 			
-				if ( recordedNoteOnMatrix[smoothIndex][1] == annotationNote){
+				if ( recordedNoteOnMatrix[outputIndex][1] == annotationNote){
 					(*fileOutput) << " corresponds to " << annotationTime;
 				}
 			(*fileOutput) << " \n";
 				
 		}
-	
-		printf("annotations: rec tick time %i vs %i midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n",  
-			   recordedNoteOnMatrix[smoothIndex][0], annotationTick, recordedNoteOnMatrix[smoothIndex][1], 
-			   beatPositions[smoothIndex], playingTime, 
-			   annotationNote, annotationLocation, annotationTime, difference);
+	 */
 		
-//		assert(annotationNote == recordedNoteOnMatrix[smoothIndex][1]);
-	assert(annotationTick == recordedNoteOnMatrix[smoothIndex][0]);
+	//useful printing stuff
+//		printf("playing time %.1f, annotation time %.1f, diff %.1f\n", playingTime, (annotationTime*1000.0), difference);
+		
+//		printf("last posn %.1f, amount since %.2f \n" lastUpdatePosition, amountSinceLastUpdate);
+		
+//		printf("annotations:Diff %f rec tick time %i vs %i midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n",  
+//			   difference, recordedNoteOnMatrix[outputIndex][0], annotationTick, recordedNoteOnMatrix[outputIndex][1], 
+//			   beatPositions[outputIndex], playingTime, 
+//			   annotationNote, annotationLocation, annotationTime, difference);
+
+	// we use exact difference as it more accurately predicts where we scheduled the note
+//		printf("diff %.1f, exact diff %.1f\n", difference, exactDifference);
+		
+		
+		//assert(annotationNote == recordedNoteOnMatrix[outputIndex][1]);
+		assert(annotationTick == recordedNoteOnMatrix[outputIndex][0]);
 	
 		smoothDifference = difference;
 		
 		if ((*differenceOutput).is_open()){
-			(*differenceOutput) << beatPositions[smoothIndex] << "," << difference << "," << playingTime << "," << (annotationTime*1000.0) << "\n";
+			(*differenceOutput) << beatPositions[outputIndex] << "," << exactDifference << "," << playingTime << "," << (annotationTime*1000.0) << annotationNote << difference <<  "\n";
 		//	printf("midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n",  
-		//		   recordedNoteOnMatrix[smoothIndex][1], 
-		//		   beatPositions[smoothIndex], playingTime, 
+		//		   recordedNoteOnMatrix[outputIndex][1], 
+		//		   beatPositions[outputIndex], playingTime, 
 		//		   annotationNote, annotationLocation, annotationTime, difference);
 		}else{
 			printf("file not open\n");
 		}
 		
-		smoothIndex++;
+		outputIndex++;
 	}
 	
-		
-	smoothPlayPosition = newPosition;
-		
+	lastUpdatePosition = newPosition;
+	lastUpdatePlayingTime = playingTime;
 }
 
 void midiEventHolder::updateCausalPlayPosition(const double& timeNow){
 	//projected position
 	
+	//first update the speed
+	updateCausalSpeed();
+	
+	causalPlayPosition += causalSpeed * (timeNow - lastCausalUpdateTime);
+	lastCausalUpdateTime = timeNow;
+	
+}
+
+void midiEventHolder::updateCausalSpeed(){
 	double difference =	bayesStruct.bestEstimate - causalPlayPosition;
 	causalSpeed = bayesStruct.speedEstimate;
 	causalSpeed += (difference/timeProjectionToMeet);
 	
 	if (causalSpeed < 0)
 		causalSpeed = 0;
-	
-	causalPlayPosition += causalSpeed * (timeNow - lastCausalUpdateTime);
-	lastCausalUpdateTime = timeNow;
-	
+
 }
+
 /*
 void midiEventHolder::updatePeriodValue(const double& millis){
 
@@ -981,7 +1037,7 @@
 			if (checkIfMatchedNote(tmpIndex))
 				ofSetColor(100,100,100);//0,0,255);
 			else if(noteOnMatches[tmpIndex]){
-				ofSetColor(255,0,255);//dark grey
+				ofSetColor(255,0,255);//pink
 			}
 			else{
 				ofSetColor(255,255,255);//255,255,255);
@@ -1011,10 +1067,14 @@
 		ofSetColor(250,250,20);//250,100,0);
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
 		
+		
+/*		
+		//cyan blue - smooth position
 		xLocation = getLocationFromMillis(smoothPlayPosition);//bayesStruct.tmpBestEstimate
-		ofSetColor(0,250,0);//250,150, 250,100,0);
-	//	ofLine(xLocation, 0, xLocation, (*screenHeight));
-		
+		ofSetColor(0,250,250);//250,150, 250,100,0);
+		ofLine(xLocation, 0, xLocation, (*screenHeight));
+*/		
+		//bright green is the causal play position
 		xLocation = getLocationFromMillis(causalPlayPosition);//bayesStruct.tmpBestEstimate
 		ofSetColor(0,250,0);//250,150, 250,100,0);
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
@@ -1049,9 +1109,16 @@
 	//ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
 	ofSetColor(255,255,255);
 	ofDrawBitmapString(timeString, 20, 60);
-	ofDrawBitmapString("diff "+ofToString(smoothDifference), 20, 140);
+	string diffString = "diff "+ofToString(smoothDifference);
+	diffString += "\ncausal posn: "+ofToString(causalPlayPosition, 0);
+	diffString += "\nsmooth posn: "+ofToString(smoothPlayPosition, 0);
+	diffString += "\noutput posn: "+ofToString(outputPosition, 0);
+	diffString += "\nbest est: "+ofToString(bayesStruct.bestEstimate, 0);
+	diffString += "\nlast best est: "+ofToString(bayesStruct.lastBestEstimateUpdateTime, 0);
 	
-//last played piutch
+	ofDrawBitmapString(diffString, 20, 140);
+	
+	//last played pitch
 	ofSetColor(0,200,0,50);
 	int yLocation = (*screenHeight) - ((lastPlayedPitch - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum));						 
 	ofRect(0,yLocation, 100,  noteHeight);
@@ -1448,7 +1515,7 @@
 /*
 JUNK SMOOTH StuffHex
  /*
- int testIndex = smoothIndex;
+ int testIndex = outputIndex;
  while (testIndex >= 0 && abs(smoothLocation - myNotation.rwcAnnotations[testIndex].beatLocation) < range){
  
  if (myNotation.rwcAnnotations[testIndex].midiNote == currentNote){
@@ -1463,7 +1530,7 @@
  testIndex--;
  }
  
- testIndex = smoothIndex;
+ testIndex = outputIndex;
  while (testIndex >= 0 && testIndex < myNotation.rwcAnnotations.size() && abs(smoothLocation - myNotation.rwcAnnotations[testIndex].beatLocation) < range){
  
  if (myNotation.rwcAnnotations[testIndex].midiNote == currentNote){
--- a/jnmr/midiEventHolder.h	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/midiEventHolder.h	Thu Mar 29 13:41:59 2012 +0100
@@ -180,11 +180,12 @@
 	
 	double causalPlayPosition;
 	void updateCausalPlayPosition(const double& timeNow);
+	void updateCausalSpeed();
 	double lastCausalUpdateTime ;
 	double causalSpeed;
 	
-	void updateSmoothPositionTo(const double& newPosition);
-	int smoothIndex;
+	void updateOutputPositionTo(const double& newPosition);
+	int outputIndex;
 	DoubleVector beatPositions;
 
 	ofstream *fileOutput;
@@ -193,5 +194,9 @@
 	double timeProjectionToMeet;///ms in future they will intersect
 	
 	double smoothDifference;
+	double lastUpdatePosition, lastUpdatePlayingTime;
+	double outputPosition;//debug variable
+	
+	void testSpeedPriorSetting();
 };
 #endif
\ No newline at end of file
--- a/jnmr/testApp.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/jnmr/testApp.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -14,13 +14,13 @@
 	root = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/Classical_RWC_Groundtruth/RM-C0";
 	outputFileRoot = "../../../data/FilesOut/rwcOutputData_RM-C0";
 	annotationRoot = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/ANNOTATION/RM-C0";
-	myfile.open("../../../data/FilesOut/exampletest2.txt");
+	//myfile.open("../../../data/FilesOut/exampletest2.txt");
 	
 	
 	
  	//diffFile.open("../../../data/FilesOut/diffTest.txt");
 	
-	midiEvents.fileOutput = &myfile;
+//	midiEvents.fileOutput = &myfile;
 	
 	
 	
@@ -220,6 +220,7 @@
 			float playedDuration = m.getArgAsFloat(0);
 			double recordedDuration =	midiEvents.recordedEventTimes[midiEvents.recordedEventTimes.size()-1];
 			midiEvents.speedPriorValue = recordedDuration/playedDuration;
+			midiEvents.testSpeedPriorSetting();
 			printf("played duration %f, recorded %f\n", playedDuration, recordedDuration);
 			printf("speed prior set to %f\n", midiEvents.bayesStruct.speedPriorValue);
 			
@@ -595,7 +596,7 @@
 	sendNoteToMuseScore();
 	
 	diffFile.close();
-	myfile.close();
+	//myfile.close();
 	
 }
 
--- a/matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -15,7 +15,7 @@
 	jnmrMidiPlayerData.clear();
 	differences.clear();
 	
-	printf("jnmrMidiPlayer : READ FILE %s\n", pathName.c_str());
+//	printf("jnmrMidiPlayer : READ FILE %s\n", pathName.c_str());
 	ifstream file ( pathName.c_str());
 	string value, tmpLine;
 	stringstream iss;
@@ -93,7 +93,7 @@
 	}//end while
 	
 	//printAnnotations();
-	printf("There are %i JNMR annotations\n", (int)jnmrMidiPlayerData.size());
+//	printf("There are %i JNMR annotations\n", (int)jnmrMidiPlayerData.size());
 	
 }
 
--- a/matchAnnotationSrc/matchAnnotations.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/matchAnnotationSrc/matchAnnotations.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -15,7 +15,7 @@
 	// "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv"
 	matchData.clear();
 	
-	printf("MATCH : READ FILE %s\n", pathName.c_str());
+//	printf("MATCH : READ FILE %s\n", pathName.c_str());
 	ifstream file ( pathName.c_str());
 	string value, tmpLine;
 	stringstream iss;
@@ -48,7 +48,7 @@
 	}//end while
 	
 //	printAnnotations();
-	printf("There are %i MATCH annotations\n", (int)matchData.size());
+//	printf("There are %i MATCH annotations\n", (int)matchData.size());
 	
 }
 
--- a/matchAnnotationSrc/testApp.cpp	Fri Mar 23 10:53:57 2012 +0000
+++ b/matchAnnotationSrc/testApp.cpp	Thu Mar 29 13:41:59 2012 +0100
@@ -4,38 +4,61 @@
 void testApp::setup(){
 	//fixed stuff
 	annotationRoot = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/ANNOTATION/RM-C0";
-	jnmrPlayerRoot = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/savedOutputs/rwcOutputData_RM-C0";
+	jnmrPlayerRoot = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/completeTestsTempoMAPestimate/rwcOutputData_RM-C0";
 	
 	createRWCfilenameStrings();
 	
+	fileNumberToTest = 0;	
+	loadAnnotation(fileNumberToTest);
+	getResults(fileNumberToTest);
+}
+
+void testApp::getResults(const int& fileID){
 	
-	std::string matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/matchOutput/RWCmatch_RM-C0";
-	std::string matchEnd = "_ob.out";
 	std::string txtEnd = ".txt";
 	//naming convention
 	//match output must also follow the RWC ID
 	//01, 02, 03 etc
 	
+	std::string matchEnd = "_ob.out";
+	matchPath = makeMatchFilename(fileID, matchEnd);//makeRWCfilename(matchRoot, fileID, matchEnd);
+	printf("MATCH PATH OB: %s\n", matchPath.c_str());
+	matchNotations.readInMatchFile(matchPath);
+	TimingResult matchObResult;
+	calculateMatchErrors(matchObResult);
+	matchOB_results.push_back(matchObResult);
 	
+	matchEnd = "_of.out";
+	matchPath = makeMatchFilename(fileID, matchEnd);//makeRWCfilename(matchRoot, fileID, matchEnd);
+	printf("MATCH PATH OF: %s\n", matchPath.c_str());
+	matchNotations.readInMatchFile(matchPath);
+	TimingResult matchOfResult;
+	calculateMatchForwardErrors(matchOfResult);
+	matchOF_results.push_back(matchOfResult);
 	
-	int fileID = 2;
-	
-	matchPath = makeRWCfilename(matchRoot, fileID, matchEnd);
-	printf("MATCH PATH\n", matchPath.c_str());
-	matchNotations.readInMatchFile(matchPath);
-
-	
-	loadAnnotation(fileID);
-
-	printf("MATCH\n");
-	calculateMatchErrors();
 	
 	jnmrPlayerPath = makeRWCfilename(jnmrPlayerRoot, fileID, txtEnd);//+ "rwcOutputData_RM-C003.txt";
 	jnmrPlayerAnnotations.readInjnmrMidiPlayerFile(jnmrPlayerPath);
 	
 	printf("JNMR DIFFERENCES\n");
-	sortDifferenceVector(jnmrPlayerAnnotations.differences);
+	TimingResult jnmrResult;
+	sortDifferenceVector(jnmrPlayerAnnotations.differences, jnmrResult);
+	JNMR_MidiMatcher_results.push_back(jnmrResult);
+
+	printf("\n");
+}
+
+
+std::string testApp::makeMatchFilename( const int& fileID, std::string matchEnd){
+	std::string matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/completeMatchOut/RWCmatch_RM-C";
 	
+	
+	string rootToUse = matchRoot;
+	if (fileID > 8){
+	rootToUse += "0";
+	}
+	string matchName = makeRWCfilename(rootToUse, fileID, matchEnd);
+	return matchName;
 }
 
 
@@ -103,7 +126,7 @@
 }
 
 
-void testApp::calculateMatchErrors(){
+void testApp::calculateMatchErrors(TimingResult& t){
 	int matchIndex = 0;
 
 	vector<float> matchDiffs;
@@ -129,38 +152,44 @@
 		matchDiffs.push_back(fabs(matchDifference));
 	}
 	
-	sortDifferenceVector(matchDiffs);
-	/*
-//GETS MEAN AND MEDIAN
-	int count = 0;
-	float total = 0;
-	
-	for (int i = 0;i < matchDiffs.size();i++){
-	//	printf("M[%i] : %f\n", i, matchDiffs[i]);
-		
-		count++;
-		total += fabs(matchDiffs[i]);
-		
-	}
-	total /= count;
-	
-	std::sort(matchDiffs.begin(), matchDiffs.end());
-	
-//	printf("SORTED TWO HUNDRED\n");
-	
-//	for (int i = 0;i < matchDiffs.size() ;i++){
-//		printf("M[%i] : %f\n", i, matchDiffs[i]);
-//	}
-	
-	printf("MATCH median %f, mean is %f\n", matchDiffs[(int)(matchDiffs.size()/2)], total);
-	*/
-
-	
+	sortDifferenceVector(matchDiffs, t);
 	
 }
 
 
-void testApp::sortDifferenceVector(vector<float> diffVec){
+void testApp::calculateMatchForwardErrors(TimingResult& t){
+	int matchIndex = 0;
+	
+	vector<float> matchDiffs;
+	
+	for (int i = 0;i < rwcAnnotations.rwcAnnotations.size();i++){
+		//		printf("rwc time %f midi time %f\n", rwcAnnotations.rwcAnnotations[i].eventTime, rwcAnnotations.rwcAnnotations[i].midiTime);
+		
+		while (matchIndex < matchNotations.matchData.size() && matchNotations.matchData[matchIndex].midiTime > rwcAnnotations.rwcAnnotations[i].midiTime)
+			matchIndex++;
+		
+		while (matchNotations.matchData[matchIndex].midiTime < rwcAnnotations.rwcAnnotations[i].midiTime)
+			matchIndex--;
+		
+		//	float matchFraction = (rwcAnnotations.rwcAnnotations[i].midiTime - matchNotations.matchData[matchIndex].midiTime)/(matchNotations.matchData[matchIndex+1].midiTime - matchNotations.matchData[matchIndex].midiTime);
+		//	matchFraction *= (matchNotations.matchData[matchIndex+1].audioTime - matchNotations.matchData[matchIndex].audioTime);
+		float matchTime = matchNotations.matchData[matchIndex].audioTime;// +matchFraction  ;
+		
+		//		printf("matchTime %f gives event time %f from flat event time %f\n", matchNotations.matchData[matchIndex].midiTime, matchTime, matchNotations.matchData[matchIndex].audioTime);
+		
+		float matchDifference = 1000.0*(matchTime - rwcAnnotations.rwcAnnotations[i].eventTime);
+		//		printf("Match diff %f\n", matchDifference);
+		
+		matchDiffs.push_back(fabs(matchDifference));
+	}
+	
+	sortDifferenceVector(matchDiffs, t);
+	
+}
+
+
+
+void testApp::sortDifferenceVector(vector<float> diffVec, TimingResult& t){
 	
 	//GETS MEAN AND MEDIAN
 	int count = 0;
@@ -172,6 +201,8 @@
 		count++;
 		total += fabs(diffVec[i]);
 		diffVec[i] = fabs(diffVec[i]);//replace with +ve value
+		
+		addToPercentiles(diffVec[i], t);
 	}
 	total /= count;
 	
@@ -183,12 +214,47 @@
 			printf("Sort[%i] : %f\n", i, diffVec[i]);
 		}
 	*/
-	printf("Count %i Median %f, mean is %f\n", count, diffVec[(int)(diffVec.size()/2)], total);
+	printf("Count %i Median %3.1f, mean is %3.1f\n", count, diffVec[(int)(diffVec.size()/2)], total);
 	
+	t.median = diffVec[(int)(diffVec.size()/2)];
+	t.mean = total;
+	t.count = count;
 	
+	for (int i = 0;i < 7;i++){
+		t.percentiles[i] = t.percentileCount[i] / count;
+		printf("Perc[%i] = %2.1f, ", i, (t.percentiles[i]*100.0));
+	}
+	printf("\n");
 
 }
 
+void testApp::addToPercentiles(float value, TimingResult& t){
+
+	if (value <= 20){
+		t.percentileCount[0]++;
+	}
+	if (value <= 40){
+		t.percentileCount[1]++;
+	}
+	if (value <= 60){
+		t.percentileCount[2]++;
+	}
+	if (value <= 100){
+		t.percentileCount[3]++;
+	}
+	if (value <= 200){
+		t.percentileCount[4]++;
+	}
+	if (value <= 500){
+		t.percentileCount[5]++;
+	}
+	if (value <= 1000){
+		t.percentileCount[6]++;
+	}
+	
+	
+}
+
 //--------------------------------------------------------------
 void testApp::update(){
 
@@ -202,6 +268,12 @@
 //--------------------------------------------------------------
 void testApp::keyPressed(int key){
 
+	if (key == ' '){
+		fileNumberToTest++;
+		loadAnnotation(fileNumberToTest);
+		getResults(fileNumberToTest);
+	}
+	
 }
 
 //--------------------------------------------------------------
@@ -242,4 +314,29 @@
 //--------------------------------------------------------------
 void testApp::dragEvent(ofDragInfo dragInfo){ 
 
-}
\ No newline at end of file
+}
+
+/*
+ //GETS MEAN AND MEDIAN
+ int count = 0;
+ float total = 0;
+ 
+ for (int i = 0;i < matchDiffs.size();i++){
+ //	printf("M[%i] : %f\n", i, matchDiffs[i]);
+ 
+ count++;
+ total += fabs(matchDiffs[i]);
+ 
+ }
+ total /= count;
+ 
+ std::sort(matchDiffs.begin(), matchDiffs.end());
+ 
+ //	printf("SORTED TWO HUNDRED\n");
+ 
+ //	for (int i = 0;i < matchDiffs.size() ;i++){
+ //		printf("M[%i] : %f\n", i, matchDiffs[i]);
+ //	}
+ 
+ printf("MATCH median %f, mean is %f\n", matchDiffs[(int)(matchDiffs.size()/2)], total);
+ */
--- a/matchAnnotationSrc/testApp.h	Fri Mar 23 10:53:57 2012 +0000
+++ b/matchAnnotationSrc/testApp.h	Thu Mar 29 13:41:59 2012 +0100
@@ -6,6 +6,15 @@
 #include "matchAnnotations.h"
 #include "jnmrMidiPlayerAnnotations.h"
 
+struct TimingResult{
+	double median;
+	double mean;
+	int count;
+	double percentileCount[7];
+	double percentiles[7];
+	int type;
+};
+
 class testApp : public ofBaseApp{
 
 	public:
@@ -33,13 +42,23 @@
 	void loadAnnotation(const int& fileID);
 	
 	string matchPath;
+	std::string makeMatchFilename( const int& fileID, std::string matchEnd);
 	
 	matchAnnotations matchNotations;
 	
 	string jnmrPlayerPath, jnmrPlayerRoot;
 	jnmrMidiPlayerAnnotations jnmrPlayerAnnotations;
 	
-	void calculateMatchErrors();
-	void sortDifferenceVector(vector<float> diffVec);
+	void calculateMatchErrors(TimingResult& t);
+	void calculateMatchForwardErrors(TimingResult& t);
 	
+	void sortDifferenceVector(vector<float> diffVec, TimingResult& t);
+	void addToPercentiles(float value, TimingResult& t);
+	
+	vector<TimingResult> matchOF_results;
+	vector<TimingResult> matchOB_results;
+	vector<TimingResult> JNMR_MidiMatcher_results;
+	
+	void getResults(const int& fileID);
+	int fileNumberToTest;
 };