changeset 9:75dcd1308658

looked at tempo process, likelihood function changed and improved. Now drawing using constrained vector function. Good working version.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 23 Aug 2011 11:20:44 +0100
parents d9a3613e7264
children 2ab6f4670cf5
files src/BayesianArrayStructure.cpp src/BayesianArrayStructure.h src/DynamicVector.cpp src/DynamicVector.h src/midiEventHolder.cpp src/midiEventHolder.h src/testApp.cpp
diffstat 7 files changed, 178 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/BayesianArrayStructure.cpp	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/BayesianArrayStructure.cpp	Tue Aug 23 11:20:44 2011 +0100
@@ -20,6 +20,7 @@
 	posterior.createVector(1);
 
 	speedPriorValue = 1.0;
+	speedEstimate = speedPriorValue;
 	
 	lastEventTime = ofGetElapsedTimeMillis();
 	
@@ -76,6 +77,7 @@
 	relativeSpeedPosterior.getMaximum();
 	
 	setSpeedPrior(speedPriorValue);
+	speedEstimate = speedPriorValue;
 	
 	prior.zero();
 	posterior.zero();
@@ -204,16 +206,20 @@
 	
 //	double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
 	
-	tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDifference*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
+	tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDifference*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.MAPestimate));
+	//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));
 	//lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
 }
 	
 void BayesianArrayStructure::updateBestEstimate(){
 //	double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
 	double timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
-	bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
+	
+	double speedEstimate = relativeSpeedPosterior.getIntegratedEstimate();
+	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimate);
+	//relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate)
+	bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
 	
 //	bestEstimate = tmpBestEstimate;
 }
@@ -268,9 +274,12 @@
 
 void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
 	int distanceMoved, newPriorIndex;
+	
+	double speedValue = relativeSpeedPosterior.offset;
+	
 	for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
 		
-		double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
+	//	double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
 		
 		//so we have moved 
 		distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
@@ -279,28 +288,37 @@
 			double speedContribution = relativeSpeedPosterior.array[i];
 			//	printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
 			
+			newPriorIndex = posterior.offset - prior.offset + distanceMoved;
+			
 			for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
 				//old posterior contributing to new prior
-				newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
+			//	newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
+				
 				if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
 					prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
 				}
 				
-			}
+				newPriorIndex++;//optimised code - the commented line above explains how this works
+			}//end for
+			
 			
 		}//if not zero
+		speedValue += relativeSpeedPosterior.scalar;
+		//optimised line
+		//as we wanted:
+		//	double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
 	}//end speed
 }
 
 
 
 void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
+
 	int distanceMoved, newPriorIndex;
-
-		
-		double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);//using max value only
+	
+	double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
 	//so for scalar 0.01, 50 -> speed value of 0.5
-	double speedContribution = relativeSpeedPosterior.array[relativeSpeedPosterior.MAPestimate];
+	double speedContribution = relativeSpeedPosterior.array[relativeSpeedPosterior.integratedEstimate];
 		//so we have moved 
 		distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
 					//	printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
@@ -344,7 +362,7 @@
 
 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
 	
-	double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
+	double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
 	//	printf("Maxspeed is %f\n", maxSpeed);
 	
 	double priorMax = posterior.getMaximum();
@@ -362,7 +380,7 @@
 //	printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
 	relativeAmount *= speedDecayAmount;
 	relativeSpeedPosterior.renormalise();
-	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
+	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.integratedEstimate, speedDecayWidth, relativeAmount);
 	
 	relativeSpeedPosterior.renormalise();
 	double newMax = relativeSpeedPosterior.getMaximum();
@@ -384,20 +402,26 @@
 	
 }
 
-void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
+void BayesianArrayStructure::setLikelihoodToConstant(){
+	//set new likelihood
+	relativeSpeedLikelihood.zero();
+	relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
+}
+
+
+void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
+	
 	//speedratio is speed of played relative to the recording
 	
 	double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
-//	printf("\nindex of likelihood would be %f\n", index);
-	if (index >= 0 && index < relativeSpeedPrior.length){
-		//then we can do update
-		
-		//set new likelihood
-		relativeSpeedLikelihood.zero();
-		relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
-		
-	relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
+	//	printf("index of likelihood would be %f for ratio %f\n", index, speedRatio);
+	if (index >= 0 && index < relativeSpeedPrior.length){	
+		relativeSpeedLikelihood.addGaussianShape(index , 5, matchFactor);
+	}
+}
 	
+	
+void BayesianArrayStructure::updateTempoDistribution(){
 
 	//copy posterior to prior
 	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
@@ -409,24 +433,9 @@
 	relativeSpeedPosterior.renormalise();
 		
 	relativeSpeedPosterior.getMaximum();	
-	}//end if within range
 	
-
-}
-
-
-void BayesianArrayStructure::setFlatTempoLikelihood(){	//set new likelihood
-	relativeSpeedLikelihood.zero();
-	relativeSpeedLikelihood.addConstant(0.3);
-}
-
-void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
-	
-	double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
-
-	if (index >= 0 && index < relativeSpeedPrior.length){
-		relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5);//*matchFactor);
-	}
+	relativeSpeedPosterior.updateIntegratedEstimate();
+	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
 }
 
 
@@ -466,23 +475,23 @@
 
 
 void BayesianArrayStructure::drawTempoArrays(){
-	ofSetColor(0,255,255);
-	relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
+	ofSetColor(0,0,255);
+//	relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
 	
 	ofSetColor(255,0,255);
 	relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
-	
-	ofSetColor(255,255,0);
+//	relativeSpeedLikelihood.drawConstrainedVector(0, 199, 0, 1000);// relativeSpeedLikelihood.arraySize);	
+	ofSetColor(255,0,0);
 	relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
 	
-	ofSetColor(0,0,255);
-	tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
+//	ofSetColor(0,0,255);
+//	tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
 	
 	ofSetColor(255,255, 255);
 	ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
 	
-	ofSetColor(0, 255, 0);
-	double fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
+	ofSetColor(155,255, 0);
+	double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
 	ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
 }
 
@@ -534,4 +543,39 @@
 		
 	}
 
-}
\ No newline at end of file
+}
+
+
+/*
+ 
+ void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
+ //speedratio is speed of played relative to the recording
+ 
+ double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
+ //	printf("\nindex of likelihood would be %f\n", index);
+ if (index >= 0 && index < relativeSpeedPrior.length){
+ //then we can do update
+ 
+ //set new likelihood
+ relativeSpeedLikelihood.zero();
+ relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
+ 
+ relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
+ 
+ 
+ //copy posterior to prior
+ relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+ 
+ //update
+ relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+ 
+ //normalise
+ relativeSpeedPosterior.renormalise();
+ 
+ relativeSpeedPosterior.getMaximum();	
+ }//end if within range
+ 
+ 
+ }
+ 
+ */
\ No newline at end of file
--- a/src/BayesianArrayStructure.h	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/BayesianArrayStructure.h	Tue Aug 23 11:20:44 2011 +0100
@@ -67,6 +67,7 @@
 	double bestEstimate;
 	void updateBestEstimate();
 	double lastBestEstimateUpdateTime;
+	double speedEstimate;
 	
 	double speedDecayWidth, speedDecayAmount;
 	void decaySpeedDistribution(double timeDifference);
@@ -77,11 +78,11 @@
 	void calculateNewPriorOffset(const double& timeDifference);
 	void setNewDistributionOffsets(const double& newOffset);
 	
-	void updateTempoDistribution(const double& speedRatio, const double& matchFactor);
+	void setLikelihoodToConstant();
+	void updateTempoLikelihood(const double& speedRatio, const double& matchFactor);
+	void updateTempoDistribution();
 	
-	void setFlatTempoLikelihood();
 	void calculateTempoUpdate();
-	void updateTempoLikelihood(const double& speedRatio, const double& matchFactor);
 	
 	void crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference);
 	void complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits);
--- a/src/DynamicVector.cpp	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/DynamicVector.cpp	Tue Aug 23 11:20:44 2011 +0100
@@ -17,6 +17,7 @@
 	MAPestimate = 0;
 	offset = 0;
 	scalar = 1;
+	integratedEstimate = length/2;
 	
 	gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2;
 	gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16);
@@ -44,6 +45,7 @@
 	}
 	length = len;
 	arraySize = array.size();
+	integratedEstimate = length/2;
 }
 
 
@@ -62,18 +64,33 @@
 
 double DynamicVector::getIntegratedEstimate(){
 	//returns the index of the integrated average - where the probability distribution is centred
-	double estimate = 0;
+	integratedEstimate = 0;
 	double integratedTotal = 0;
 	for (int i = 0;i < length;i++){
-		estimate += array[i]*i;
+		integratedEstimate += array[i]*i;
 		integratedTotal += array[i];
 	}
 	if (integratedTotal > 0){
-		estimate /= integratedTotal;
+		integratedEstimate /= integratedTotal;
 	}
-	return estimate;
+	return integratedEstimate;
 }
 
+void DynamicVector::updateIntegratedEstimate(){
+	//returns the index of the integrated average - where the probability distribution is centred
+	integratedEstimate = 0;
+	double integratedTotal = 0;
+	for (int i = 0;i < length;i++){
+		integratedEstimate += array[i]*i;
+		integratedTotal += array[i];
+	}
+	if (integratedTotal > 0){
+		integratedEstimate /= integratedTotal;
+	}
+
+}
+
+
 void DynamicVector::zero(){
 	for (int i = 0;i < array.size();i++)
 		array[i] = 0;
@@ -123,12 +140,16 @@
 void DynamicVector::addGaussianShape(double mean, double StdDev, double factor){
 	
 	int i;
+	double std_dev_factor = (2*StdDev*StdDev);
 	factor *= (1/(StdDev*sqrt(2*PI)));
-	for (i=0;i<array.size();i++){
-		array[i] += factor*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev));
+	int minVal = max(0, (int)(mean - 4.8*StdDev));
+	
+	for (i=minVal;i < maxVal;i++){
+		array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor));
 	}
 	
-	//addGaussianShapeByLookupTable(mean, StdDev, factor);
+//	addGaussianShapeByLookupTable(mean, StdDev, factor);
 }
 
 void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor){
@@ -206,8 +227,9 @@
 
 		
 		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
-		double screenHeight = ofGetHeight();
+		double screenHeight = (double) ofGetHeight();
 		double maxVal = getMaximum();
+	
 		int startInt = max(1,minIndex+1);
 		int endInt = min(maxIndex, (int)array.size());
 		double heightConstant = screenHeight / maxVal;
--- a/src/DynamicVector.h	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/DynamicVector.h	Tue Aug 23 11:20:44 2011 +0100
@@ -31,7 +31,8 @@
 	void addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor);
 	double gaussianLookupTable[GAUSSIAN_LOOKUP_LENGTH];
 	double gaussianLookupMean, gaussianLookupStdDev;
-	
+	double integratedEstimate;
+	void updateIntegratedEstimate();
 	
 	void drawVector(const int& minIndex, const int& maxIndex);
 	void drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex);
--- a/src/midiEventHolder.cpp	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/midiEventHolder.cpp	Tue Aug 23 11:20:44 2011 +0100
@@ -31,7 +31,7 @@
 	likelihoodWidth = 100;
 	likelihoodToNoiseRatio = 0.02;
 	
-	bayesStruct.speedLikelihoodNoise = 0.02;//was 0.05
+	bayesStruct.speedLikelihoodNoise = 0.1;//was 0.05
 	bayesStruct.speedDecayWidth = 20;
 	bayesStruct.speedDecayAmount = 10;
 	
@@ -54,6 +54,8 @@
 	
 	confidenceWeightingUsed = false;
 	
+	drawPhaseMode = true;
+	
 	printf("lookup index %f value %f\n", bayesStruct.prior.getLookupIndex(100, 30., 10.0), bayesStruct.prior.gaussianLookupTable[(int)bayesStruct.prior.getLookupIndex(100, 30., 10.0)]);
 }
 
@@ -144,7 +146,7 @@
 //	double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime; 
 	double timeDifference = timePlayed - bayesStruct.lastEventTime; 
 	
-	printf("note %i played at %f and last event %f\n", pitch, timePlayed, bayesStruct.lastEventTime);
+//	printf("note %i played at %f and last event %f\n", pitch, timePlayed, bayesStruct.lastEventTime);
 	//addnoise to the tempo distribution
 	//bayesStruct.decaySpeedDistribution(timeDifference);
 	if (timeDifference > 50){
@@ -165,8 +167,8 @@
 	timeString += "  offset "+ofToString(bayesStruct.posterior.offset , 0);
 	timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0); 
 //	timeString += " Previous time" + ofToString(newMAPestimateTime,0);
-	timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 2);
-	timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 2);
+	timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 2);
+	timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 2);
 	
 //	newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
 //	timeString += " :  Predicted MAP time" + ofToString(newMAPestimateTime,0);
@@ -179,8 +181,8 @@
 	
 	timeString += " \n :  new offset " + ofToString(bayesStruct.prior.offset , 0);
 	timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1);
-	timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.MAPestimate, 1);
-	timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 1);
+	timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 1);
+	timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 1);
 	
 	
 	//be able to draw the prior in correct location relative to the midi notes
@@ -329,14 +331,19 @@
 	//	printMatchesFound();
 	//	printMatchMatrix();
 	//	printf("possible notes \n");
+	bool needToUpdate = false;
+	bayesStruct.setLikelihoodToConstant();
 	
 	
 	for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
 		//iterate through the recently matched events - even dodgy matches included
 		//size, index of match0, index of match1, ....
+		
+		
 		int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1];
 		
 		int previousIndex = currentPlayedIndex-1;
+
 		
 		while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) {
 			double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex];
@@ -361,8 +368,10 @@
 					//	matchString += " speed: "+ofToString(speedRatio, 3);
 					//	commented for debug
 					
-					bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match
-					
+					//bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match
+					double amount =	(1-bayesStruct.speedLikelihoodNoise)/10;
+					bayesStruct.updateTempoLikelihood(speedRatio, amount);
+					needToUpdate = true;
 				}
 				//		printf("\n");	
 			}
@@ -371,11 +380,15 @@
 		}//end while previousindex countdown
 	}//end for loop through possible current matches
 	
+	if (needToUpdate)
+		bayesStruct.updateTempoDistribution();
+	
 	//printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
 }
 
 
 void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){
+	bool needToUpdate = false;
 	
 	int currentPlayedIndex = playedNoteOnMatrix.size()-1;
 	//	printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]);
@@ -383,6 +396,7 @@
 	//	printMatchMatrix();
 	//	printf("possible notes \n");
 	
+	bayesStruct.setLikelihoodToConstant();
 	
 	for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){
 		//iterate through the recently matched events - even dodgy matches included
@@ -418,9 +432,10 @@
 					 
 					//	matchString += " speed: "+ofToString(speedRatio, 3);
 					//	commented for debug
-					double weighting = previousMatchConfidence * currentMatchConfidence * 0.1;
-					bayesStruct.updateTempoDistribution(speedRatio, weighting);//second paramter is confidence in the match
-					
+					double weighting = previousMatchConfidence * currentMatchConfidence ;
+					double amount =	(1-bayesStruct.speedLikelihoodNoise)*weighting/10;
+					bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match
+					needToUpdate = true;
 				}
 				//		printf("\n");	
 			}
@@ -429,6 +444,8 @@
 		}//end while previousindex countdown
 	}//end for loop through possible current matches
 	
+	if (needToUpdate)
+		bayesStruct.updateTempoDistribution();
 	//printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate));
 }
 
@@ -453,14 +470,15 @@
 }
 
 
-void midiEventHolder::drawFile(){
+void midiEventHolder::drawMidiFile(){
+	
 	//draws midi file on scrolling screen
 	int size = recordedNoteOnMatrix.size();
 	if (size > 0){
 		
 		numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in
 		
-	//	numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down
+		//	numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down
 		timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen);
 		
 		while (noteArrayIndex < recordedNoteOnMatrix.size() && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] )
@@ -485,14 +503,14 @@
 			if (checkIfMatchedNote(tmpIndex))
 				ofSetColor(0,0,255);
 			else if(noteOnMatches[tmpIndex]){
-			ofSetColor(255,0,255);
+				ofSetColor(255,0,255);
 			}else{
 				ofSetColor(255,255,255);
 			}
-		
 			
-
-	//		 XXX replace ofgetwidth below
+			
+			
+			//		 XXX replace ofgetwidth below
 			//if (tmpIndex >= 0 && tmpIndex < size)
 			int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen;
 			int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen;
@@ -505,7 +523,7 @@
 		
 		
 		int xLocation;// = getLocationFromTicks(tickLocation);
-	//	ofLine(xLocation, 0, xLocation, (*screenHeight));
+		//	ofLine(xLocation, 0, xLocation, (*screenHeight));
 		
 		//orange line at best estimate
 		xLocation = getLocationFromMillis(bayesStruct.bestEstimate);
@@ -523,22 +541,28 @@
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
 		xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth);
 		ofLine(xLocation, 0, xLocation, (*screenHeight));
-		 
+		
 		
 	}	
 	
-	
-	
 	ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20);
 	
 	ofDrawBitmapString(timeString, 20, 60);
 	
+	
+}
+
+void midiEventHolder::drawFile(){	
+		drawMidiFile();
+		
+	
 //	bayesStruct.drawArrays();
 	
 //	ofSetColor(200,200,0);
 //	bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800);
 	
 	//need to draw arrays within correct timescope
+	if (drawPhaseMode)
 	bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen));
 	
 	if (drawTempoMode)
--- a/src/midiEventHolder.h	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/midiEventHolder.h	Tue Aug 23 11:20:44 2011 +0100
@@ -47,7 +47,7 @@
 	double mouseX;
 	
 	void clearAllEvents();
-	bool drawTempoMode;
+	bool drawTempoMode, drawPhaseMode;
 	
 	double minimumMatchSpeed , maximumMatchSpeed;
 	
@@ -88,6 +88,7 @@
 	DoubleMatrix beatPeriodMatrix;
 	
 	void drawFile();
+	void drawMidiFile();
 	void reset();
 	void setMatchedNotesBackToFalse();
 	
--- a/src/testApp.cpp	Fri Aug 19 19:45:46 2011 +0100
+++ b/src/testApp.cpp	Tue Aug 23 11:20:44 2011 +0100
@@ -126,6 +126,9 @@
 	if (key == 't')
 		midiEvents.drawTempoMode = !midiEvents.drawTempoMode;
 	
+	if (key == 'r')
+		midiEvents.drawPhaseMode = !midiEvents.drawPhaseMode;
+	
 	if (key == 'o'){
 		//open audio file
 		string *filePtr;