changeset 34:9d2a651a87b2

autoomatically set prior that matches the durations of the songs. Using 120 bpm as default for the recorded part.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Wed, 14 Dec 2011 11:35:31 +0000
parents fa527df85c2c
children 6cd3e0075adf
files .DS_Store jnmr/BayesianArrayStructure.cpp jnmr/BayesianArrayStructure.h jnmr/CannamMidiFileLoader.cpp jnmr/CannamMidiFileLoader.h jnmr/MidiInputStream.h jnmr/midiEventHolder.cpp jnmr/midiEventHolder.h jnmr/testApp.cpp jnmr/testApp.h
diffstat 10 files changed, 268 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
Binary file .DS_Store has changed
--- a/jnmr/BayesianArrayStructure.cpp	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/BayesianArrayStructure.cpp	Wed Dec 14 11:35:31 2011 +0000
@@ -144,7 +144,7 @@
 	if (*realTimeMode)
 		lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
 	//cannot just be zero - offline bug
-	printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
+	//printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
 	
 	resetArrays();
 }
@@ -190,12 +190,15 @@
 
 void BayesianArrayStructure::updateTmpBestEstimate(const double& timeDifference){
 	//input is the time since the start of playing
-	
 //	double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
-	
-	tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDifference*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
+	double timeDiff = timeDifference;
+	if (*realTimeMode)
+		timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
+
+	double tmp = relativeSpeedPosterior.getIntegratedEstimate();
+	tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
 	// 
-	//printf("tmp best %f and best %f time diff %f posterior MAP %f at speed %f\n", tmpBestEstimate, bestEstimate, timeDifference, posterior.getIndexInRealTerms(posterior.MAPestimate), relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate));
+	//printf("tmp best %f and best %f time diff %f posterior MAP %f at speed %f\n", 0Estimate, bestEstimate, timeDifference, posterior.getIndexInRealTerms(posterior.MAPestimate), relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate));
 	//lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
 }
 	
@@ -209,18 +212,16 @@
 	if (*realTimeMode)
 		timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
 	
-	double speedEstimate;
+	//lastbest is time we started playing
+	
 	if (usingIntegratedTempoEstimate)
-		speedEstimate = relativeSpeedPosterior.getIntegratedEstimate();
+		speedEstimateIndex = relativeSpeedPosterior.getIntegratedEstimate();
 	else
-		speedEstimate = relativeSpeedPosterior.MAPestimate;
+		speedEstimateIndex = relativeSpeedPosterior.MAPestimate;
 	
-	
-	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimate);
-	//relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate)
+	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimateIndex);
 	bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
 	
-//	bestEstimate = tmpBestEstimate;
 }
 
 void BayesianArrayStructure::calculatePosterior(){
@@ -434,7 +435,8 @@
 		
 	relativeSpeedPosterior.getMaximum();	
 	
-//	relativeSpeedPosterior.updateIntegratedEstimate();
+	//relativeSpeedPosterior.updateIntegratedEstimate(); - could be swayed when off to side 
+	//so now limited to where there is room sround the MAP estimate
 	relativeSpeedPosterior.updateLimitedIntegratedEstimate();
 	
 	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
--- a/jnmr/BayesianArrayStructure.h	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/BayesianArrayStructure.h	Wed Dec 14 11:35:31 2011 +0000
@@ -67,7 +67,7 @@
 	double bestEstimate;
 	void updateBestEstimate(const double& timeDifference);
 	double lastBestEstimateUpdateTime;
-	double speedEstimate;
+	double speedEstimate, speedEstimateIndex;
 	
 	double speedDecayWidth, speedDecayAmount;
 	void decaySpeedDistribution(double timeDifference);
@@ -94,6 +94,6 @@
 	bool* realTimeMode;
 	bool usingIntegratedTempoEstimate;
 	double relativeSpeedLikelihoodStdDev;
-	
+
 };
 #endif
--- a/jnmr/CannamMidiFileLoader.cpp	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/CannamMidiFileLoader.cpp	Wed Dec 14 11:35:31 2011 +0000
@@ -13,6 +13,7 @@
 CannamMidiFileLoader::CannamMidiFileLoader(){
 	chopBeginning = true;
 	firstTickTime = 0;
+	printMidiInfo = false;
 }
 
 int CannamMidiFileLoader::loadFile(std::string& filename, midiEventHolder& myMidiEvents){
@@ -23,6 +24,7 @@
 		
 		
 		setTempoFromMidiValue(500000, myMidiEvents);//default is 120bpm
+	
 		myMidiEvents.pulsesPerQuarternote = 240;//default
 		//myMidiEvents.measureVector.push_back(0);
 		//int main(int argc, char **argv)
@@ -106,10 +108,10 @@
 							long tempo = (((m0 << 8) + m1) << 8) + m2;
 								//if (printMidiInfo)
 								cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl;
-							setTempoFromMidiValue(tempo, myMidiEvents);
+							//setTempoFromMidiValue(tempo, myMidiEvents);
 							DoubleVector tmp;
 
-							
+					/*		
 							double lastTickInMillis = 0;
 							double millisTimeNow = lastTickInMillis;
 							int tickInterval = 0;
@@ -128,8 +130,28 @@
 							tmp.push_back(60000000.0 / double(tempo));	
 							tmp.push_back(millisTimeNow);
 							myMidiEvents.periodValues.push_back(tmp);
+					 */
 							
-							printf("tick[%i]: TEMPO period %f : time now %f\n", t, 60000000.0 / double(tempo), millisTimeNow);
+							double lastTickInMillis = 0;
+							double millisTimeNow = lastTickInMillis;
+							int tickInterval = 0;
+							if (myMidiEvents.periodValues.size() > 0){
+								lastTickInMillis = myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][2];
+								tickInterval = t  - myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][0];
+								millisTimeNow = lastTickInMillis + (myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][1]*tickInterval);
+								
+							}
+							
+							tmp.push_back(t);
+							
+							
+							tmp.push_back(60000000.0 / double(tempo));	
+							double tmpTempoVal = 60000000.0 / double(tempo);
+							tmp.push_back(millisTimeNow);
+							//if (tmpTempoVal > 180.0)
+							myMidiEvents.periodValues.push_back(tmp);
+							
+							printf("tick[%i]: TEMPO %d tempoVal %f : time now %f\n", t, tempo, tmpTempoVal, millisTimeNow);
 							//printf("period double is %f\n", myMidiEvents.period);
 						
 						}
@@ -189,8 +211,10 @@
 						<< " pitch " << j->getPitch()
 						<< " velocity " << j->getVelocity() 
 						<< "event time " << myMidiEvents.getEventTimeMillis(t) << endl;
-				
 						
+						printf("%i channel %i durn %i pitch %i vel %i event time %f\n", t, ch, j->getDuration(), j->getPitch(), j->getVelocity(), myMidiEvents.getEventTimeMillis(t));
+						
+						/*
 						if (noteOnIndex == 0  || t < firstTickTime){
 							//easier just to pick the minimum
 							firstTickTime = t;
@@ -198,15 +222,15 @@
 						}
 						
 						noteOnIndex++;
-						
+						*/
 						v.clear();
 						
 					//	printf("note on at %i\n", t);
 						
-						if (!chopBeginning)
+						//if (!chopBeginning)
 							v.push_back(t);
-						else
-							v.push_back(t - firstTickTime);
+						//else
+						//	v.push_back(t - firstTickTime);
 						
 						v.push_back(j->getPitch());
 						v.push_back(j->getVelocity());
@@ -291,8 +315,8 @@
 			
 			
 		}
-	if (printMidiInfo)
-	myMidiEvents.printRecordedEvents();
+//	if (printMidiInfo)
+//	myMidiEvents.printRecordedEvents();
 	
 	//printMeasuresSoFar(myMidiEvents);
 	
@@ -308,6 +332,9 @@
 	myMidiEvents.correctTiming(myMidiEvents.recordedNoteOnMatrix);
 	myMidiEvents.doublecheckOrder(myMidiEvents.recordedNoteOnMatrix);
 
+	if (chopBeginning)
+		chopBeginningfromEvents(myMidiEvents);
+	
 	createEventTiming(myMidiEvents);
 	
 	printf("BEFORE DOING MEASURE UPDATE\n first tick pos is %i\n", firstTickTime);
@@ -315,21 +342,47 @@
 	if (chopBeginning)
 		correctMeasuresTiming(myMidiEvents);
 	
-	if (printMidiInfo)
-	myMidiEvents.printRecordedEvents();	
+//	if (printMidiInfo)
+//	myMidiEvents.printRecordedEvents();	
 	
 	printf("Duration of MIDI file is %f \n", myMidiEvents.recordedEventTimes[myMidiEvents.recordedEventTimes.size()-1]);
-	
+	printf("And first note offset is %i ticks == %f msec \n", firstTickTime, firstNoteTime);
 	//printMeasuresSoFar(myMidiEvents);
 	
 }//end cannam midi main
 	
 
+void CannamMidiFileLoader::chopBeginningfromEvents(midiEventHolder&  myMidiEvents){
+
+	firstTickTime = myMidiEvents.recordedNoteOnMatrix[0][0];
+	firstNoteTime = myMidiEvents.getEventTimeMillis(myMidiEvents.recordedNoteOnMatrix[0][0]);
+	myMidiEvents.firstEventOffsetTimeMillis = firstNoteTime;
+	
+	printf("BEFORE chop - FIRST NOTE IS %f and tick %i\n", firstNoteTime, firstTickTime);
+//	myMidiEvents.printRecordedEvents();
+	
+	for (int i = 0;i < myMidiEvents.recordedNoteOnMatrix.size();i++){
+		myMidiEvents.recordedNoteOnMatrix[i][0] -= firstTickTime;
+	}
+	
+	//here are period values, but we dont use them
+	for (int i = 0;i < myMidiEvents.periodValues.size();i++){
+		myMidiEvents.periodValues[i][0] -= firstTickTime;
+		myMidiEvents.periodValues[i][2] -= firstNoteTime;
+		printf("[%i], period values(%i):: @ %f is %f\n", (int)myMidiEvents.periodValues[i][0], i, myMidiEvents.periodValues[i][2], myMidiEvents.periodValues[i][1]);
+	}
+	
+	printf("\n\n\nAFTER chop - \n");
+//	myMidiEvents.printRecordedEvents();
+	
+}
+
 void CannamMidiFileLoader::createEventTiming( midiEventHolder& myMidiEvents){
 	
 	long t;
-	t = myMidiEvents.recordedNoteOnMatrix[0][0];
-	firstNoteTime = myMidiEvents.getEventTimeMillis(t);
+//	t = myMidiEvents.recordedNoteOnMatrix[0][0];
+//	firstTickTime = t;
+//	firstNoteTime = myMidiEvents.getEventTimeMillis(firstTickTime);
 	
 	for (int i = 0; i < myMidiEvents.recordedNoteOnMatrix.size();i++){
 		t = myMidiEvents.recordedNoteOnMatrix[i][0];
@@ -337,11 +390,12 @@
 		if (!chopBeginning)
 			myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t));
 		else {
-			myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t) - firstNoteTime);
-			
+			myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t));// - firstticktime			
 		}
 	}
 	
+	
+	
 }
 
 void CannamMidiFileLoader::setTempoFromMidiValue(long tempo,  midiEventHolder& myMidiEvents){
@@ -387,7 +441,7 @@
 		myMidiEvents.measureVector[i] -= firstTickTime;
 	}
 	printf("AFTER DOING MEASURE UPDATE\n");
-	printMeasuresSoFar(myMidiEvents);
+	//printMeasuresSoFar(myMidiEvents);
 }
 
 void CannamMidiFileLoader::printMeasuresSoFar(midiEventHolder& myMidiEvents){
--- a/jnmr/CannamMidiFileLoader.h	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/CannamMidiFileLoader.h	Wed Dec 14 11:35:31 2011 +0000
@@ -29,6 +29,7 @@
 	double firstNoteTime;
 	int firstTickTime;
 	bool chopBeginning;
+	void chopBeginningfromEvents(midiEventHolder&  myMidiEvents);
 	
 	typedef std::vector<int> IntVector;
 	IntVector v;
@@ -40,6 +41,6 @@
 	bool printMidiInfo;
 	void printMeasuresSoFar(midiEventHolder& myMidiEvents);
 	void correctMeasuresTiming(midiEventHolder& myMidiEvents);
-	
+	double fileDuration;
 };
 #endif
\ No newline at end of file
--- a/jnmr/MidiInputStream.h	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/MidiInputStream.h	Wed Dec 14 11:35:31 2011 +0000
@@ -47,6 +47,7 @@
 	int* transposeVal;
 	
 	double* factor;
+
 	
 };
 #endif
--- a/jnmr/midiEventHolder.cpp	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/midiEventHolder.cpp	Wed Dec 14 11:35:31 2011 +0000
@@ -14,12 +14,13 @@
 
 midiEventHolder::midiEventHolder(){
 //	recordedNoteOnIndex = 0;
+	alignmentPosition = 0;
 	
 	useTempoPrior = false;//puts sine wave round tempo
 	confidenceWeightingUsed = true;
 	newOptimalMethod = true;
 	
-	matchWindowWidth = 8000;//window size for matching in ms 
+	matchWindowWidth = 16000;//window size for matching in ms 
 	interNoteRange = 1600;//preferred duration
 	//so max here is really four
 	
@@ -71,7 +72,7 @@
 	
 	
 	speedWindowWidthMillis =  1600;//4000
-	speedPriorValue = 1.0;
+
 	noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum);
 	
 
@@ -96,7 +97,7 @@
 	
 	noteArrayIndex = 0;
 	tickLocation = 0;
-	lastPeriodUpdateTime = getTimeNow(0);//ofGetElapsedTimeMillis();
+	startPlayingTime = getTimeNow(0);//ofGetElapsedTimeMillis();
 	bayesStruct.lastEventTime = getTimeNow(0);//ofGetElapsedTimeMillis();
 	numberOfScreensIn = 0;
 //	recordedNoteOnIndex = 0;
@@ -111,13 +112,29 @@
 	recordedTotalNoteCounterByPitch.clear();
 	recordedTotalNoteCounterByPitch.assign(127,0);
 	totalNoteCounterIndex = 0;
-	
+
 	interNoteIntervals.clear();
 	
+	smoothPlayPosition = 0.0;
+//	relativeSpeedForSmooth = 1.0;
+//	storedSmoothPlayPosition = smoothPlayPosition;
+//	lastSmoothUpdateTime = getTimeNow(0);
+	
+	printf("reset speed prior is %f\n", speedPriorValue);
 	bayesStruct.resetSpeedToOne();
 	bayesStruct.setSpeedPrior(speedPriorValue);
 	setMatchedNotesBackToFalse();
-	
+
+	periodCounter = 0;
+	for (int i = 0;i < periodValues.size();i++){
+	//	printf("period at %f is %f\n", periodValues[i][2], periodValues[i][1]);
+	}
+/*	if (periodValues.size() > 0){
+		updatePeriodValue(0);// periodValues[0][2];
+		printf("Resetting period to %f , size is %i\n", period,  (int)periodValues.size());
+	}
+*/
+	//period = 500.0;
 }
 
 void midiEventHolder::setMatchedNotesBackToFalse(){
@@ -152,7 +169,8 @@
 
 
 double midiEventHolder::getEventTimeTicks(double millis){
-	return (millis * pulsesPerQuarternote / period);
+	return 0.0;
+	//return (millis * pulsesPerQuarternote / period);
 }
 
 double midiEventHolder::getEventTimeMillis(double ticks){
@@ -190,8 +208,6 @@
 //	double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime; 
 	double timeDifference = timePlayed - bayesStruct.lastEventTime; 
 	
-	
-	
 	//printf("note %i played at %f and last event %f time difference %f and current best estmate %f\n", pitch, timePlayed, bayesStruct.lastEventTime, timeDifference, bayesStruct.bestEstimate);
 
 	//addnoise to the tempo distribution
@@ -202,10 +218,12 @@
 //	bayesStruct.addTriangularNoiseToSpeedPosterior(timeDifference * 10 / 100.);
 	}
 	
-	bayesStruct.updateTmpBestEstimate(timeDifference);// debug - didnt work	bayesStruct.bestEstimate = bayesStruct.tmpBestEstimate;
+//	bayesStruct.updateTmpBestEstimate(timeDifference);// debug - didnt work	bayesStruct.bestEstimate = bayesStruct.tmpBestEstimate;
 	bayesStruct.updateBestEstimate(timeDifference);
+
 	bayesStruct.lastBestEstimateUpdateTime = getTimeNow(timePlayed);
-	
+	//updatePeriodValue(bayesStruct.lastBestEstimateUpdateTime);
+
 //	double newMAPestimateTime = bayesStruct.posterior.getIndexInRealTerms(bayesStruct.posterior.MAPestimate);
 	//was offset + bayesStruct.posterior.MAPestimate; but this doesnt include scalar to convert to millis
 
@@ -260,6 +278,8 @@
 	updateTempo();
 	//calcuateNewInterNoteIntervals();
 	}
+	
+	//storedSmoothPlayPosition = smoothPlayPosition;
 	 
 }
 
@@ -807,6 +827,7 @@
 
 
 void midiEventHolder::updatePlayPosition(){
+	//timeDifference = ofGetElapsedTimeMillis() - startPlayingTime;//elpased 
 	
 	//in actual fact if we are changing the speed of the play position 
 	//we will need to update this via the file
@@ -814,24 +835,48 @@
 	//actually time since beginning of file i think
 	
 	double timeDifference = 0;
-	if (runningInRealTime)
-		timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;//elpased - lastperiodupdatetime
+	
+	if (runningInRealTime){
+		
+		bayesStruct.updateBestEstimate(timeDifference);
+		//	bayesStruct.updateTmpBestEstimate(timeDifference);
+	}
+	
+	if (smoothPlayPosition < bayesStruct.bestEstimate)
+		smoothPlayPosition = bayesStruct.bestEstimate;
+	
+//	playPositionInMillis = timeDifference;//based on updating from when we change period
+	//this to be added
+
 	
 	//this is time diff in milliseconds
 	//then we have 
 	double quarterNoteIntervals = (timeDifference / period);
 	tickLocation = quarterNoteIntervals * pulsesPerQuarternote; 
 	
-	playPositionInMillis = timeDifference;//based on updating from when we change period
-	//this to be added
-	
-	if (runningInRealTime)
-	bayesStruct.updateBestEstimate(timeDifference);
-	
 	updateNoteCounter();
 	
 }
 
+
+void midiEventHolder::updatePeriodValue(const double& millis){
+
+	double tmp = period;
+/*	
+	while (periodCounter >= 0 && periodCounter < periodValues.size()-1 && periodValues[periodCounter][2] < millis){
+		periodCounter++;
+	}
+	while (periodCounter > 0 && periodValues[periodCounter][2] > millis){
+		periodCounter--;
+	}
+ */
+	//period = periodValues[periodCounter][1];
+	
+	if (period != tmp){
+		printf("new period at %f of %f\n", millis, period);
+	}
+}
+
 void  midiEventHolder::updateNoteCounter(){
 	while (totalNoteCounterIndex < bestMatchIndex){
 		int tmpPitch = recordedNoteOnMatrix[totalNoteCounterIndex][1];
@@ -902,11 +947,11 @@
 		
 		//orange line at best estimate
 		xLocation = getLocationFromMillis(bayesStruct.bestEstimate);
-		ofSetColor(80,80,80);//250,100,0);
+		ofSetColor(250,250,20);//250,100,0);
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
 		
-		xLocation = getLocationFromMillis(bayesStruct.tmpBestEstimate);
-		ofSetColor(150,150,150);//250,100,0);
+		xLocation = getLocationFromMillis(smoothPlayPosition);//bayesStruct.tmpBestEstimate
+		ofSetColor(0,250,0);//250,150, 250,100,0);
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
 		
 		
@@ -1008,6 +1053,8 @@
 void midiEventHolder::drawFile(){	
 		drawMidiFile();
 		
+	ofSetColor(0,0,255);
+	ofDrawBitmapString("period"+ofToString(period, 2), ofGetWidth() - 180, 20);
 	
 //	bayesStruct.drawArrays();
 	
@@ -1075,7 +1122,9 @@
 }
 
 int midiEventHolder::getLocationFromTicks(double tickPosition){
-	return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen);
+	return 0;
+//	return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen);
+//not used
 }
 
 int midiEventHolder::getLocationFromMillis(double millisPosition){
@@ -1092,8 +1141,8 @@
 
 
 void midiEventHolder::setStartPlayingTimes(){
-	lastPeriodUpdateTime = getTimeNow(0);//ofGetElapsedTimeMillis();
-	startTime = lastPeriodUpdateTime;
+	startPlayingTime = getTimeNow(0);//ofGetElapsedTimeMillis();
+	//startTime = startPlayingTime;
 	
 /*	
  	bayesStruct.lastEventTime = 0;//ofGetElapsedTimeMillis();
@@ -1213,4 +1262,33 @@
 	for (int i = 0;i < recordedTotalNoteCounterByPitch.size();i++){
 		printf("RECORDED TOTAL[%i] := %i", i, recordedTotalNoteCounterByPitch[i]);
 	}
-}
\ No newline at end of file
+}
+
+/*	double timeDiff = 0;//timeDifference;
+ if (runningInRealTime)
+ timeDiff = ofGetElapsedTimeMillis() - lastSmoothUpdateTime;
+ //		bayesStruct.lastBestEstimateUpdateTime;
+ 
+ //smoothPlayPosition = bayesStruct.bestEstimate + 100;
+ //relativeSpeedForSmooth = 0.1;
+ //bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate);
+ //   speedEstimate*2;
+ 
+ smoothPlayPosition = storedSmoothPlayPosition + timeDiff * relativeSpeedForSmooth;// * bayesStruct.speedEstimate;
+ storedSmoothPlayPosition = smoothPlayPosition;
+ lastSmoothUpdateTime = getTimeNow(bayesStruct.lastBestEstimateUpdateTime);
+ updateSmoothPlaySpeed();
+ //bayesStruct.posterior.getIndexInRealTerms(bayesStruct.posterior.MAPestimate) 
+ 
+ }
+ 
+ void  midiEventHolder::updateSmoothPlaySpeed(){
+ //project where current play pos will be in two seconds and aim for it.
+ double timeToAimForMillis = 2000.0;
+ //double timeDiff = ofGetElapsedTimeMillis() - bayesStruct.lastBestEstimateUpdateTime;//since the update need to get to where we are
+ double projection = bayesStruct.bestEstimate + bayesStruct.speedEstimate*timeToAimForMillis;//
+ double timeDifferenceFromSmooth = projection - smoothPlayPosition;
+ relativeSpeedForSmooth = timeDifferenceFromSmooth / timeToAimForMillis;
+ 
+ }
+*/ 
--- a/jnmr/midiEventHolder.h	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/midiEventHolder.h	Wed Dec 14 11:35:31 2011 +0000
@@ -123,10 +123,10 @@
 	int* screenHeight;
 	float noteHeight;
 	float tempo;
-	double lastPeriodUpdateTime;
+	double startPlayingTime;
 	int lastPlayedPitch;
 	
-	double playPositionInMillis;
+	//double playPositionInMillis;
 	
 	double timeOffsetForScreen;
 	
@@ -138,7 +138,7 @@
 	double speedPriorValue;
 	int bestMatchIndex;
 	string timeString;
-	double startTime;
+	//double startTime;
 	int speedWindowWidthMillis;
 	
 	bool confidenceWeightingUsed;
@@ -164,6 +164,16 @@
 	void printInterNoteIntervals();
 	int interNoteRange;
 	DoubleMatrix periodValues;
+	int 	periodCounter;
+	void updatePeriodValue(const double& millis);
 	
+	double smoothPlayPosition;
+//	double storedSmoothPlayPosition;
+//	double lastSmoothUpdateTime;
+//	double relativeSpeedForSmooth;
+//	void updateSmoothPlaySpeed();;
+	//best alignment
+	double alignmentPosition;
+	double firstEventOffsetTimeMillis;
 };
 #endif
\ No newline at end of file
--- a/jnmr/testApp.cpp	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/testApp.cpp	Wed Dec 14 11:35:31 2011 +0000
@@ -8,7 +8,18 @@
 //--------------------------------------------------------------
 void testApp::setup(){
 	
-
+	
+	myfile.open("../../../data/FilesOut/exampletest.txt");
+	if (myfile.is_open())
+	{
+		myfile << "This is a line.\n";
+		myfile << "This is another line.\n";
+		myfile.close();
+		printf("WRITING TO TEXT FILE\n");
+	}
+	else cout << "Unable to open file";
+	
+	
  this->args->printArgs();
 	this->args->printOpts();
 	midiFileName = "../../../data/frerejacques.mid";
@@ -33,7 +44,7 @@
 	transpose = 0;
 	noteInStream.transposeVal = &transpose;
 	
-	noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events
+	noteInStream.startTime = &midiEvents.startPlayingTime;//point start time of note in stream to the same time in MIDI events
 
 	noteInStream.factor = &midiEvents.ticksFactor;
 	printf("TICKS FACTOR %f \n", midiEvents.ticksFactor);//noteInStream->factor)
@@ -99,7 +110,7 @@
 					startPlaying();
 					printf("starting to PLAY!!!");
 				}
-				printf("MIDI NOTE %i \n", newMidiOnPitch);
+			//	printf("MIDI NOTE %i \n", newMidiOnPitch);
 				midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
 				noteInStream.newNoteCounted(newMidiOnPitch);
 			}
@@ -111,7 +122,7 @@
 			float speedPrior = m.getArgAsFloat(0);
 			printf("speed prior set to %f\n", speedPrior);
 			midiEvents.speedPriorValue = speedPrior;
-			midiEvents.bayesStruct.speedPriorValue = speedPrior;
+			//midiEvents.bayesStruct.speedPriorValue = speedPrior;
 		}
 		
 		if ( m.getAddress() == "/startplaying" )
@@ -181,6 +192,18 @@
 		
 		}
 		
+		if ( m.getAddress() == "/duration" )
+		{
+			
+			float playedDuration = m.getArgAsFloat(0);
+			double recordedDuration =	midiEvents.recordedEventTimes[midiEvents.recordedEventTimes.size()-1];
+			midiEvents.speedPriorValue = recordedDuration/playedDuration;
+			printf("played duration %f, recorded %f\n", playedDuration, recordedDuration);
+			printf("speed prior set to %f\n", midiEvents.bayesStruct.speedPriorValue);
+			
+		}
+		
+		
 	}//end while osc
 	if (midiEvents.recordedEventTimes.size() > 0)
 	checkNewScoreNote();
@@ -327,30 +350,33 @@
 	
 	ofSetHexColor(0xFF0000);
 //	ofDrawBitmapString(info, 20, 20);
+	
 	midiEvents.drawMidiFile(noteInStream.midiInputEvents);
 
-//	ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 60, 50);
-	//ofDrawBitmapString("filename "+museScoreFilename, 20, 80);
-	string ratingString = ofToString(performanceRating*100,0)+"%";
-						   if (performanceRating > 0.84)
-						   ratingString += "!* *";
-						   string extraText = "";
-						   if (performanceRating > 0.9){
-						   extraText += " pretty good, huh?";
-						   }
-						   if (performanceRating > 0.95)
-						   extraText = " blimey! ";
-						   if (performanceRating > 0.97)
-						   extraText = " maestro!";
-						   
-						   ratingString += extraText;  
-	verdana30.drawString(ratingString, 20, 60);
+	drawMuseScoreText();
 	
 	ofSetHexColor(0x000000);
 	ofDrawBitmapString(midiPortName, 20, ofGetHeight() - 20);
 	
 }
 
+void testApp::drawMuseScoreText(){
+	string ratingString = ofToString(performanceRating*100,0)+"%";
+	if (performanceRating > 0.84)
+		ratingString += "!* *";
+	string extraText = "";
+	if (performanceRating > 0.9){
+		extraText += " pretty good, huh?";
+	}
+	if (performanceRating > 0.95)
+		extraText = " blimey! ";
+	if (performanceRating > 0.97)
+		extraText = " maestro!";
+	
+	ratingString += extraText;  
+	verdana30.drawString(ratingString, 20, 60);
+}
+
 //--------------------------------------------------------------
 void testApp::keyPressed(int key){
 
--- a/jnmr/testApp.h	Mon Dec 12 12:46:17 2011 +0000
+++ b/jnmr/testApp.h	Wed Dec 14 11:35:31 2011 +0000
@@ -22,7 +22,7 @@
 #include "MIDIFileReader.h"
 #include "ofxFileDialogOSX.h"
 #include "drawMidiNotes.h"
-#include "DynamicBayesianArray.h"
+
 #include "CannamMidiFileLoader.h"
 #include <iostream>
 #include "midiEventHolder.h"
@@ -31,6 +31,12 @@
 #include "MidiInputStream.h"
 #include "ofxArgs.h"
 
+
+// basic file operations for text file stuff
+#include <iostream>
+#include <fstream>
+using namespace std;
+
 #define PORT 12121
 #define SEND_PORT 5282
 #define HOST "localhost"
@@ -123,6 +129,13 @@
 	
 	bool readyToStart;
 	void prepareToStartOnNextNote();
+	void drawMuseScoreText();
+	
+
+	
+	
+	//file output
+	ofstream myfile;
 };
 
 #endif