changeset 4:4a8e6a6cd224

optimised draw function in dynamic vector class. Added Gaussian lookup but not yet used.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 19 Aug 2011 15:53:04 +0100
parents de86d77f2612
children 195907bb8bb7
files src/BayesianArrayStructure.cpp src/BayesianArrayStructure.h src/CannamMidiFileLoader.cpp src/DynamicVector.cpp src/DynamicVector.h src/midiEventHolder.cpp
diffstat 6 files changed, 119 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/BayesianArrayStructure.cpp	Fri Aug 19 02:36:34 2011 +0100
+++ b/src/BayesianArrayStructure.cpp	Fri Aug 19 15:53:04 2011 +0100
@@ -30,6 +30,7 @@
 	 tmpPrior.translateDistribution(20);
 	 */
 	tmpBestEstimate = 0;
+	crossUpdateTimeThreshold = 100;
 }
 
 BayesianArrayStructure::BayesianArrayStructure(int length){
@@ -250,38 +251,70 @@
 	
 	double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
 	
+
 	prior.zero();//kill prior
 	calculateNewPriorOffset(timeDifference);//set new prior offset here
 	
-	for (int i = 0;i < speed.arraySize;i++){
-//		printf("[%i] %f\n", i, speed.array[i]);
-		//set speed
-		double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
+	if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
+		complexCrossUpdate(timeDifferenceInPositionVectorUnits);
+	else
+		translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);	
+			
 
-		//so we have moved 
-		int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
-		
-		if (speed.array[i] != 0){
-			
-		//	printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
-			
-		for (int postIndex = 0;postIndex < position.arraySize;postIndex++){
-			//old posterior contributing to new prior
-			int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved;
-			if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
-				prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]);
-			//	printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]);
-			}
-		
-		}
-			
-		}//if not zero
-	}//end speed
 	updateCounter++;
 	prior.renormalise();
 
 }
 
+void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
+	int distanceMoved, newPriorIndex;
+	for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
+		
+		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
+	
+		if (relativeSpeedPosterior.array[i] != 0){
+			double speedContribution = relativeSpeedPosterior.array[i];
+			//	printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
+			
+			for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
+				//old posterior contributing to new prior
+				newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
+				if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
+					prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
+				}
+				
+			}
+			
+		}//if not zero
+	}//end speed
+}
+
+
+
+void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
+	int distanceMoved, newPriorIndex;
+
+		
+		double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);//using max value only
+	//so for scalar 0.01, 50 -> speed value of 0.5
+	double speedContribution = relativeSpeedPosterior.array[relativeSpeedPosterior.MAPestimate];
+		//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);
+			
+			for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
+				//old posterior contributing to new prior
+				newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
+				if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
+					prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
+				}
+				
+			}
+	
+}
 
 void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(const double& std_dev){
 	tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
--- a/src/BayesianArrayStructure.h	Fri Aug 19 02:36:34 2011 +0100
+++ b/src/BayesianArrayStructure.h	Fri Aug 19 15:53:04 2011 +0100
@@ -84,8 +84,12 @@
 	void updateTempoLikelihood(const double& speedRatio, const double& matchFactor);
 	
 	void crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference);
+	void complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits);
+	void translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits);
+	double crossUpdateTimeThreshold;//time after which we do complex update of multiple speeds
 	
 	double speedPriorValue;
 	
+	
 };
 #endif
--- a/src/CannamMidiFileLoader.cpp	Fri Aug 19 02:36:34 2011 +0100
+++ b/src/CannamMidiFileLoader.cpp	Fri Aug 19 15:53:04 2011 +0100
@@ -147,12 +147,12 @@
 				switch (j->getMessageType()) {
 						
 					case MIDI_NOTE_ON:
-						cout << t << ": Note: channel " << ch
+				/*		cout << t << ": Note: channel " << ch
 						<< " duration " << j->getDuration()
 						<< " pitch " << j->getPitch()
 						<< " velocity " << j->getVelocity() 
 						<< "event time " << myMidiEvents.getEventTimeMillis(t) << endl;
-
+				*/
 						
 						if (noteOnIndex == 0){
 							firstNoteTime = myMidiEvents.getEventTimeMillis(t);
@@ -177,7 +177,7 @@
 						myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t));
 						else {
 						myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t) - firstNoteTime);
-							printf("chopping beginning %f \n", myMidiEvents.getEventTimeMillis(t) - firstNoteTime);
+					//		printf("chopping beginning %f \n", myMidiEvents.getEventTimeMillis(t) - firstNoteTime);
 						}
 
 						break;
--- a/src/DynamicVector.cpp	Fri Aug 19 02:36:34 2011 +0100
+++ b/src/DynamicVector.cpp	Fri Aug 19 15:53:04 2011 +0100
@@ -17,6 +17,14 @@
 	MAPestimate = 0;
 	offset = 0;
 	scalar = 1;
+	
+	gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2;
+	gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16);
+	double factor = 1.0;//(1.0 / (gaussianLookupStdDev*sqrt(2*PI)) );//1.0;//-1.0/(2*PI*sqrt(gaussianLookupStdDev));
+	for (int i = 0;i < GAUSSIAN_LOOKUP_LENGTH;i++){
+	gaussianLookupTable[i] = factor*exp(-1.0*(i-gaussianLookupMean)*(i-gaussianLookupMean)/(2.0*gaussianLookupStdDev*gaussianLookupStdDev));
+	}
+	
 }
 
 void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){
@@ -113,14 +121,42 @@
 }
 
 void DynamicVector::addGaussianShape(double mean, double StdDev, double factor){
+	
 	int i;
 	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));
 	}
+	
+	//addGaussianShapeByLookupTable(mean, StdDev, factor);
+}
+
+void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor){
+	int i;
+	int lookupIndex ;
+	factor *= (1/(StdDev*sqrt(2*PI)));
+	for (i=0;i<array.size()-1;i++){
+		lookupIndex = round(getLookupIndex(i, mean, StdDev));
+		array[i] += factor*gaussianLookupTable[lookupIndex];
+	}
 	//printf("ADDED GAUSSIAN SHAPE %i\n", (int)array.size());
 }
 
+double DynamicVector::getLookupIndex(const int& i, const double& mean, const double& StdDev){
+	
+	double Z = ((double)i - mean)/StdDev;
+	double lookupIndex = Z*gaussianLookupStdDev + gaussianLookupMean;
+	
+	if (lookupIndex < 0)
+		lookupIndex = 0;
+	
+	if (lookupIndex >= GAUSSIAN_LOOKUP_LENGTH)
+		lookupIndex = GAUSSIAN_LOOKUP_LENGTH-1;
+	
+//	(i - mean)*(i-mean)*(GAUSSIAN_LOOKUP_LENGTH*GAUSSIAN_LOOKUP_LENGTH/16.0)/(StdDev*StdDev);
+	return lookupIndex;
+}
+
 void DynamicVector::addTriangularShape(double mean, double width, double factor){
 	int i;
 
@@ -172,9 +208,15 @@
 		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
 		double screenHeight = ofGetHeight();
 		double maxVal = getMaximum();
-		
-		for (int i = max(1,minIndex+1);i < min(maxIndex, (int)array.size());i++){
-		ofLine (stepSize*(i-1), screenHeight * (1 - array[i-1] / maxVal), stepSize*i, screenHeight * (1 - array[i] / maxVal) );
+		int startInt = max(1,minIndex+1);
+		int endInt = min(maxIndex, (int)array.size());
+		double heightConstant = screenHeight / maxVal;
+		int lastHeightPixel = heightConstant * (1 - array[startInt-1]);
+		int newHeightPixel;
+		for (int i = startInt;i < endInt;i++){
+			newHeightPixel = (int) heightConstant * (1 - array[i]);
+			ofLine (stepSize*(i-1), lastHeightPixel, stepSize*i, newHeightPixel);
+			lastHeightPixel = newHeightPixel;
 		}
 	
 }
--- a/src/DynamicVector.h	Fri Aug 19 02:36:34 2011 +0100
+++ b/src/DynamicVector.h	Fri Aug 19 15:53:04 2011 +0100
@@ -14,6 +14,7 @@
 
 #ifndef _DYNAMIC_VECTOR
 #define _DYNAMIC_VECTOR
+#define GAUSSIAN_LOOKUP_LENGTH 1000000
 
 class DynamicVector{
 public:
@@ -26,6 +27,11 @@
 	DoubleVector array;
 	double getMaximum();
 	double getIntegratedEstimate();
+	double getLookupIndex(const int& i, const double& mean, const double& StdDev);
+	void addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor);
+	double gaussianLookupTable[GAUSSIAN_LOOKUP_LENGTH];
+	double gaussianLookupMean, gaussianLookupStdDev;
+	
 	
 	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 02:36:34 2011 +0100
+++ b/src/midiEventHolder.cpp	Fri Aug 19 15:53:04 2011 +0100
@@ -25,13 +25,13 @@
 	noteMinimum = 30;
 	noteMaximum = 96;
 	
-	minimumMatchSpeed = 0.7;
-	maximumMatchSpeed = 1.3;
+	minimumMatchSpeed = 0.0;
+	maximumMatchSpeed = 2.0;
 
 	likelihoodWidth = 100;
 	likelihoodToNoiseRatio = 0.02;
 	
-	bayesStruct.speedLikelihoodNoise = 0.05;//was 0.05
+	bayesStruct.speedLikelihoodNoise = 0.02;//was 0.05
 	bayesStruct.speedDecayWidth = 20;
 	bayesStruct.speedDecayAmount = 10;
 	
@@ -49,6 +49,8 @@
 	
 	speedPriorValue = 1.0;
 	noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum);
+	
+	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)]);
 }