changeset 28:49a5b023df1e

Hackday files comitted - version as demo'd at London hackday
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 05 Dec 2011 07:00:47 +0000
parents fa1890efa044
children 69083ce48b83
files hackday/BayesianArrayStructure.cpp hackday/BayesianArrayStructure.h hackday/DynamicBayesianArray.cpp hackday/DynamicBayesianArray.h hackday/DynamicVector.cpp hackday/DynamicVector.h hackday/drawMidiNotes.cpp hackday/drawMidiNotes.h hackday/main.cpp hackday/midiEventHolder.cpp hackday/musescore info.txt hackday/testApp.cpp
diffstat 12 files changed, 1627 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/BayesianArrayStructure.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,590 @@
+/*
+ *  BayesianArrayStructure.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+//look at reset speed to one - what does this do? - get rid of?
+
+
+#include "BayesianArrayStructure.h"
+
+BayesianArrayStructure::BayesianArrayStructure(){
+	printf("Bayesian structure: DeFault constructor called");
+	usingIntegratedTempoEstimate = true;//false: use max index
+	
+	relativeSpeedLikelihoodStdDev = 5.0;
+	
+	prior.createVector(1);
+	likelihood.createVector(1);
+	posterior.createVector(1);
+
+	
+	speedPriorValue = 1.0;
+	speedEstimate = speedPriorValue;
+	
+	lastEventTime = 0;//ofGetElapsedTimeMillis();
+
+	tmpBestEstimate = 0;
+	crossUpdateTimeThreshold = 60;
+	priorWidth = 50;
+	
+}
+
+BayesianArrayStructure::BayesianArrayStructure(int length){
+	printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length);
+	//this constructor isnt called  it seems
+	prior.createVector(length);
+	likelihood.createVector(length);
+	posterior.createVector(length);
+	
+	lastEventTime = 0;
+	
+
+}
+
+
+
+void BayesianArrayStructure::resetSize(int length){
+	printf("BAYESIAN STRUCTURE size is : %i\n", length);
+	
+	prior.createVector(length);
+	likelihood.createVector(length);
+	posterior.createVector(length);
+	
+	acceleration.createVector(length);
+	
+}
+
+
+
+void BayesianArrayStructure::resetSpeedToOne(){
+	relativeSpeedPrior.zero();
+	relativeSpeedPosterior.zero();
+	relativeSpeedLikelihood.zero();
+	
+	
+	relativeSpeedPosterior.addGaussianShape(100, 20, 0.8);
+	relativeSpeedPosterior.renormalise();
+	relativeSpeedPosterior.getMaximum();
+	
+	setSpeedPrior(speedPriorValue);
+	speedEstimate = speedPriorValue;
+	
+	prior.zero();
+	posterior.zero();
+
+	posterior.addToIndex(0, 1);
+	posterior.renormalise();
+	
+
+	//acceleration.addGaussianShape(2000, 20, 0.8);
+	
+}
+
+void BayesianArrayStructure::setSpeedPrior(double f){	
+	speedPriorValue = f;
+	int index = relativeSpeedPosterior.getRealTermsAsIndex(speedPriorValue);
+	relativeSpeedPosterior.zero();
+	relativeSpeedPosterior.addGaussianShape(index, priorWidth, 0.8);
+	relativeSpeedPosterior.renormalise();
+	relativeSpeedPosterior.getMaximum();
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+	printf("BAYES STRUCTU ' SPEED PRIOR %f . index %i\n", speedPriorValue, index);
+	
+}
+
+void BayesianArrayStructure::resetSpeedSize(int length){
+	printf("BAYESIAN SPEED size is : %i\n", length);
+	
+	relativeSpeedPrior.createVector(length);
+	relativeSpeedLikelihood.createVector(length);
+	relativeSpeedPosterior.createVector(length);
+	tmpPosteriorForStorage.createVector(length);
+	
+	
+
+}
+
+void BayesianArrayStructure::setRelativeSpeedScalar(double f){
+	relativeSpeedPrior.scalar = f;
+	relativeSpeedPosterior.scalar = f;
+	relativeSpeedLikelihood.scalar = f;
+}
+
+
+void BayesianArrayStructure::setPositionDistributionScalar(double f){
+	if (f > 0){
+	prior.scalar = f;
+	posterior.scalar = f;
+	likelihood.scalar = f;
+	}
+}
+
+void BayesianArrayStructure::simpleExample(){
+	relativeSpeedPosterior.getMaximum();
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+}
+
+void BayesianArrayStructure::copyPriorToPosterior(){
+
+	for (int i = 0;i < prior.arraySize;i++){
+		posterior.array[i] = prior.array[i];
+	}
+}
+
+void BayesianArrayStructure::setStartPlaying(){
+	
+	lastEventTime = 0;
+	bestEstimate = 0;
+	lastBestEstimateUpdateTime = 0;
+	if (*realTimeMode)
+		lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
+	//cannot just be zero - offline bug
+	printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
+	
+	resetArrays();
+}
+
+void BayesianArrayStructure::resetArrays(){
+	//called when we start playing
+	
+	prior.zero();
+	likelihood.zero();
+	posterior.zero();
+	
+	updateCounter = 0;
+	
+	posterior.offset = 0;
+	setNewDistributionOffsets(0);
+	
+	int zeroIndex = posterior.getRealTermsAsIndex(0);
+	
+	posterior.addGaussianShape(zeroIndex, 500, 1);
+	//	posterior.addToIndex(0, 1);
+	likelihood.addConstant(1);
+	
+	updateCounter = 0;
+	
+
+	printf("bayes reset arrays - best estimate %f\n", lastBestEstimateUpdateTime);
+	
+	setSpeedPrior(speedPriorValue);
+}
+
+
+void BayesianArrayStructure::zeroArrays(){
+	prior.zero();
+	likelihood.zero();
+	posterior.zero();
+	
+	relativeSpeedPrior.zero();
+	relativeSpeedPosterior.zero();
+	relativeSpeedLikelihood.zero();
+
+}
+
+
+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);
+	// 
+	//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(const double& timeDifference){
+//	double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
+	
+	double timeDiff = timeDifference;
+	
+	//Using timedifferencfe here will make it go wrong. Is time since beginning of playing
+	
+	if (*realTimeMode)
+		timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
+	
+	double speedEstimate;
+	if (usingIntegratedTempoEstimate)
+		speedEstimate = relativeSpeedPosterior.getIntegratedEstimate();
+	else
+		speedEstimate = relativeSpeedPosterior.MAPestimate;
+	
+	
+	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimate);
+	//relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate)
+	bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
+	
+//	bestEstimate = tmpBestEstimate;
+}
+
+void BayesianArrayStructure::calculatePosterior(){
+	//posterior.doProduct(prior, likelihood);
+	
+	int i;
+	for (i = 0;i < posterior.length;i++){
+		posterior.array[i] = likelihood.array[i] * prior.array[i];
+	}
+	
+	
+	posterior.renormalise();
+	
+
+
+	 
+}
+
+
+
+
+void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
+	prior.offset = newOffset;
+	likelihood.offset = newOffset;
+	//posterior.offset = newOffset;
+}
+
+
+void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
+	//set the cutoff for offset of position first! XXX
+	
+//	printf("time difference %f, ", timeDifference);
+	
+	double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
+	
+
+	prior.zero();//kill prior
+	calculateNewPriorOffset(timeDifference);//set new prior offset here
+	
+	if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
+		complexCrossUpdate(timeDifferenceInPositionVectorUnits);
+	else
+		translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);	
+			
+
+	updateCounter++;
+	prior.renormalise();
+
+}
+
+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
+		
+		//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);
+			
+			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;
+				
+				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.integratedEstimate);
+	//so for scalar 0.01, 50 -> speed value of 0.5
+	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);
+			
+			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);
+	
+	for (int i = 0;i < relativeSpeedPosterior.length;i++){
+		tmpPosteriorForStorage.addGaussianShape(i, std_dev, relativeSpeedPosterior.array[i]);
+		}
+												
+	tmpPosteriorForStorage.renormalise();
+	
+	relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);											
+}
+
+
+void BayesianArrayStructure::addTriangularNoiseToSpeedPosterior(const double& std_dev){
+	tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
+	
+	for (int i = 0;i < relativeSpeedPosterior.length;i++){
+		//adding a linear amount depending on distance
+		tmpPosteriorForStorage.addTriangularShape(i, std_dev*2.0, relativeSpeedPosterior.array[i]);
+	}
+	
+	tmpPosteriorForStorage.renormalise();
+	
+	relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);											
+}
+
+void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
+	
+	double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
+	//	printf("Maxspeed is %f\n", maxSpeed);
+	
+	double priorMax = posterior.getMaximum();
+	double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
+	double newMaxLocation = posterior.MAPestimate + distanceTravelled;
+	//	printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
+	
+}
+
+
+void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
+	
+	// commented for the moment
+	 double relativeAmount = max(1.0, timeDifference/1000.);
+//	printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
+	relativeAmount *= speedDecayAmount;
+	relativeSpeedPosterior.renormalise();
+	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.integratedEstimate, speedDecayWidth, relativeAmount);
+	
+	relativeSpeedPosterior.renormalise();
+	double newMax = relativeSpeedPosterior.getMaximum();
+	
+	//old code
+//	relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
+	//relativeSpeedPosterior.addConstant(1);
+	
+	/*
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+	relativeSpeedLikelihood.zero();
+	relativeSpeedLikelihood.addConstant(0.2);
+	relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+	relativeSpeedPosterior.renormalise();
+	 */
+	
+
+	
+}
+
+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("index of likelihood would be %f for ratio %f\n", index, speedRatio);
+	if (index >= 0 && index < relativeSpeedPrior.length){	
+		relativeSpeedLikelihood.addGaussianShape(index , relativeSpeedLikelihoodStdDev, matchFactor);
+	}
+}
+	
+
+
+void BayesianArrayStructure::updateTempoDistribution(){
+
+	//copy posterior to prior
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+
+	//update
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+
+	//normalise
+	relativeSpeedPosterior.renormalise();
+		
+	relativeSpeedPosterior.getMaximum();	
+	
+	relativeSpeedPosterior.updateIntegratedEstimate();
+	speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
+}
+
+
+void BayesianArrayStructure::calculateTempoUpdate(){
+	//copy posterior to prior
+	relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
+	
+	//update
+	relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
+	
+	//normalise
+	relativeSpeedPosterior.renormalise();
+	
+	relativeSpeedPosterior.getMaximum();	
+	
+}
+
+
+void BayesianArrayStructure::drawArrays(){
+	
+	//bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
+	//bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
+	
+	int displaySize = prior.arraySize;
+	ofSetColor(0,0,255);
+	prior.drawVector(0, displaySize);
+	ofSetColor(0,255,0);
+	likelihood.drawVector(0, displaySize);
+	ofSetColor(255,0,255);
+	posterior.drawVector(0, displaySize);
+	
+	
+	
+}
+
+
+void BayesianArrayStructure::drawTempoArrays(){
+	ofSetColor(0,0,255);
+//	relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
+	
+	ofSetColor(0,150,255);
+	relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
+	
+//	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(255,255, 255);
+	ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
+	
+	ofSetColor(25, 0, 250);
+	double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
+	ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
+	
+	ofSetColor(255, 0, 20);
+	fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
+	ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
+	 
+	
+}
+
+
+void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
+
+	screenWidth = ofGetWidth();
+	
+	int startArrayIndex = 0;
+	
+	if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
+		//i.e. the array is on the page
+	
+	while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
+		startArrayIndex++;
+	}
+	int endArrayIndex = prior.arraySize-1;
+	//could find constraints here
+	if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
+		endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
+	
+	//so we need to figure where start and end array are on screen
+	int startScreenPosition, endScreenPosition;
+	double screenWidthMillis = endTimeMillis - startTimeMillis;
+		
+	startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
+	endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
+		
+	ofSetColor(0,0,100);
+	string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
+	relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
+//	relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+")  ";
+	relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
+//	ofDrawBitmapString(relativeString, 100, 180);
+	
+		
+		
+	ofSetColor(100,100,100);//255, 255, 0);
+	likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+
+//	ofSetColor(0,0,200);
+	ofSetColor(170,170,170);//00,200);
+	prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+		ofSetColor(0,0,150);	
+//	ofSetColor(200, 0, 0);
+	posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+		
+//	ofSetColor(0, 200, 255);
+//	acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
+		
+		
+	}
+
+}
+
+
+/*
+ 
+ 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/BayesianArrayStructure.h	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,99 @@
+/*
+ *  BayesianArrayStructure.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+#ifndef BAYESIAN_ARRAY_STRUCTURE
+#define BAYESIAN_ARRAY_STRUCTURE
+
+
+#include "ofMain.h"
+//#include "DynamicBayesianArray.h"
+#include "DynamicVector.h"
+
+class BayesianArrayStructure {
+	
+public:
+//	BayesianArrayStructure();
+	BayesianArrayStructure();
+	BayesianArrayStructure(int length);
+	
+	void calculatePosterior();
+	void drawArrays();
+	void drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis);
+
+	void drawTempoArrays();
+	
+	void resetSize(int length);
+	void resetArrays();
+	void simpleExample();
+	void setStartPlaying();
+	void zeroArrays();
+	
+	double screenWidth;
+	
+	void copyPriorToPosterior();
+//	DynamicBayesianArray bayesArray;
+	
+	double lastEventTime;
+	double likelihoodNoise;
+	double speedLikelihoodNoise;
+	
+	//DynamicVector tmpPrior;
+	DynamicVector tmpPosteriorForStorage;
+	DynamicVector prior;
+	DynamicVector posterior;
+	DynamicVector likelihood;
+	
+	DynamicVector relativeSpeedPrior;
+	DynamicVector relativeSpeedLikelihood;
+	DynamicVector relativeSpeedPosterior;
+	DynamicVector acceleration;
+	
+	double tmpBestEstimate;
+	void updateTmpBestEstimate(const double& timeDifference);
+	
+	int updateCounter;
+	
+	void setPositionDistributionScalar(double f);
+	
+	void resetSpeedToOne();
+	void addGaussianNoiseToSpeedPosterior(const double& std_dev);
+	void addTriangularNoiseToSpeedPosterior(const double& std_dev);
+	
+	double bestEstimate;
+	void updateBestEstimate(const double& timeDifference);
+	double lastBestEstimateUpdateTime;
+	double speedEstimate;
+	
+	double speedDecayWidth, speedDecayAmount;
+	void decaySpeedDistribution(double timeDifference);
+	
+	void resetSpeedSize(int length);
+	void setRelativeSpeedScalar(double f);
+	void setSpeedPrior(double f);
+	void calculateNewPriorOffset(const double& timeDifference);
+	void setNewDistributionOffsets(const double& newOffset);
+	
+	void setLikelihoodToConstant();
+	void updateTempoLikelihood(const double& speedRatio, const double& matchFactor);
+	void updateTempoDistribution();
+	
+	void calculateTempoUpdate();
+	
+	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;
+	int priorWidth;
+	bool* realTimeMode;
+	bool usingIntegratedTempoEstimate;
+	double relativeSpeedLikelihoodStdDev;
+	
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/DynamicBayesianArray.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,326 @@
+/*
+ *  DynamicDynamicBayesianArray.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "DynamicBayesianArray.h"
+#include "math.h"
+#include "ofMain.h"
+
+DynamicBayesianArray::DynamicBayesianArray(){
+	
+//	prior.createVector(240);
+//	likelihood.createVector(240);
+//	posterior.createVector(240);	
+	testVector.createVector(240);
+	testVector.addGaussianShape(100,10, 0.1);
+	
+	
+	likelihoodNoise = 0.5;
+	likelihoodMean = ARRAY_SIZE/2;
+	likelihoodStdDev = ARRAY_SIZE / 12;
+	initialiseArray();
+}
+
+void DynamicBayesianArray::initialiseArray(){
+	
+	//maximumIndex = 12;//change this
+	setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);	
+	setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev);
+	
+	calculatePosterior();
+	renormalisePosterior();
+	posteriorDecayRate = 0.06;
+	
+	eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4
+	earlySixteenthNoteProportion = 0;
+	lateSixteenthNoteProportion = 0;
+	decayNoiseAmount = 0.1;
+	decayNoiseStdDev = ARRAY_SIZE/24;
+	standardDeviation = likelihoodStdDev;
+	setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev);
+	
+	setGaussianLikelihood(likelihoodMean, likelihoodStdDev);
+}
+
+
+void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+		//posterior[i] = prior[i];
+	}
+}
+
+void DynamicBayesianArray::setGaussianPosterior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+
+void DynamicBayesianArray::setGaussianLikelihood(float mean, float StdDev){
+	if (mean >= 0 && mean <= ARRAY_SIZE){
+		int i;	float eighthDifference;
+		int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+		float mainDifference;
+		float gaussianProportion = 1 - likelihoodNoise;
+		
+		for (i=0;i < ARRAY_SIZE;i++){
+			
+			mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean));
+			//without * (1 - eighthNoteProportion)
+			likelihood[i] = gaussianProportion  * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+			
+			likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+			//likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+			//(double) (likelihoodNoise / ARRAY_SIZE) );
+		}
+		//	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+	}//end if mean within limits
+}
+
+void DynamicBayesianArray::calculatePosterior(){
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] = likelihood[i] * prior[i];
+	}
+	//renormalisePosterior();
+}
+
+
+float DynamicBayesianArray::getMaximum(float *ptr, int length){
+	int i;
+	float max = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max)
+			max = *(ptr+i);
+	}
+	maximumValue = max;
+	return max;
+}
+
+float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){
+	float returnArray[2];
+	int i;
+	float max = 0;
+	maximumIndex = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max){
+			max = *(ptr+i);
+			maximumIndex = i;
+		}
+	}
+	returnArray[0] = max;
+	returnArray[1] = maximumIndex;
+	maximumValue = max;
+	return &returnArray[0];
+}
+
+
+
+double DynamicBayesianArray::getIntegratedEstimateIndex(){
+	int i;
+	float integratedQuantity = 0;
+	float integratedTotal = 0;
+	double integratedIndex = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		integratedQuantity += posterior[i];//the values of the probability distribution
+		integratedTotal += i*posterior[i];
+	}
+	if (integratedQuantity > 0){
+		integratedIndex = integratedTotal / integratedQuantity;
+	}
+	integratedEstimate = (float) integratedIndex;
+	return integratedIndex;
+}
+
+
+double DynamicBayesianArray::calculateStandardDeviation(){
+	
+	double total = 0;
+	double pdfSum;
+	double variance = 0;
+	for (int i=0;i < ARRAY_SIZE;i++){	
+		//*posterior[i] * 		
+		total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution
+		pdfSum += posterior[i];
+	}
+	
+	if (pdfSum > 0)
+		variance = total / pdfSum;
+	else 
+		variance = ARRAY_SIZE;
+	
+	standardDeviation = sqrt(variance);
+	return standardDeviation;
+}
+
+
+
+void DynamicBayesianArray::renormaliseArray(float *ptr, int length){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < length;i++){
+		totalArea += *(ptr+i);
+	}
+	
+	for (i=0;i < length;i++){
+		*(ptr+i) /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::resetPrior(){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = posterior[i];
+	}
+}
+
+void DynamicBayesianArray::renormalisePosterior(){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < ARRAY_SIZE;i++){
+		totalArea += posterior[i];
+	}
+	
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::decayPosterior(){
+	float *pointer;
+	pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE);	
+	float maximum;
+	maximum = *pointer;
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	maximumIndex = *(pointer+1);
+}
+
+void DynamicBayesianArray::setDecayNoiseGaussian(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+void DynamicBayesianArray::decayPosteriorWithGaussianNoise(){
+	
+	int i;
+	float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE);
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount;
+		//posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	
+}
+
+void DynamicBayesianArray::resetMaximumPosterior(){
+	int i;
+	float max = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		if (posterior[i]>max){
+			maximumIndex = i;
+			max = posterior[i];
+		}
+	}
+}
+
+void DynamicBayesianArray::translateDistribution(int translationIndex){
+	int tmpIndex;
+	//copy array
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		tempPosteriorArray[i] =	posterior[i] ;
+	}
+	//translate values
+	for (i=0;i < ARRAY_SIZE;i++){
+		tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE;
+		posterior[tmpIndex] = tempPosteriorArray[i]; 
+	}
+	//now delete tmp array
+}
+
+
+void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){
+	
+	if (minIndex >= 0){
+	
+		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
+		double screenHeight = ofGetHeight();
+		double maxVal = getMaximum(&arrayToDraw[0], maxIndex);
+
+		for (int i = minIndex+1;i < maxIndex;i++){
+		
+			ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) );
+		}
+	
+	}
+		
+		
+}
+
+ 
+
+/*
+void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){
+
+	if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0))
+
+}
+*/
+/*
+ void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){
+ //this has eighth and sixteenth positions included
+ 
+ if (mean >= 0 && mean <= ARRAY_SIZE){
+ int i;	float eighthDifference;
+ int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+ int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;;
+ int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;;
+ 
+ float mainDifference, sixteenthDifference;
+ float gaussianProportion = 1 - likelihoodNoise;
+ float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion);
+ 
+ for (i=0;i < ARRAY_SIZE;i++){
+ 
+ mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean));
+ likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+ 
+ eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition);
+ eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ 
+ 
+ likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+ //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+ //(double) (likelihoodNoise / ARRAY_SIZE) );
+ }
+ //	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+ }//end if mean within limits
+ }
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/DynamicBayesianArray.h	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,105 @@
+/*
+ *  DynamicBayesianArray.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+/*
+ *  DynamicBayesianArray.cpp
+ *  bayesianTest5
+ *
+ *  Created by Andrew Robertson on 08/05/2010.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+/*
+ *  DynamicBayesianArray.h
+ *  bayesianTest5
+ *
+ *  Created by Andrew Robertson on 08/05/2010.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "ofMain.h"
+
+#include "DynamicVector.h"
+
+#ifndef	_DYNAMIC_BAYESIAN_ARRAY
+#define _DYNAMIC_BAYESIAN_ARRAY
+
+#define ARRAY_SIZE 240
+
+
+class DynamicBayesianArray{
+	
+public:
+	
+	DynamicBayesianArray();
+	void initialiseArray();
+	
+//	void setGaussianLikelihoodForBeats(float mean, float StdDev);		
+	void setGaussianLikelihood(float mean, float StdDev);	
+	void setGaussianPrior(float mean, float StdDev);
+	void setGaussianPosterior(float mean, float StdDev);
+	
+	void calculatePosterior();
+	void renormalisePosterior();
+	void resetMaximumPosterior();//resets the max index
+	void decayPosteriorWithGaussianNoise();
+	void translateDistribution(int translationIndex);
+	void setDecayNoiseGaussian(float mean, float StdDev);
+	double calculateStandardDeviation();
+	
+	int arraySize;
+	
+	
+	float getMaximum(float *ptr, int length);
+	void renormaliseArray(float *ptr, int length);
+	void resetPrior();
+	void decayPosterior();
+	float* getMaximumEstimate(float *ptr, int length);
+	double getMaximumIndex();//return the index where the probability is maximal
+	double getIntegratedEstimateIndex();
+	
+//	void drawArray(const int& minIndex, const int& maxIndex);
+	void drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex);
+	void drawDoubleArray(double* arrayToDraw, const int& minIndex, const int& maxIndex);		
+
+	
+	typedef std::vector<double> DoubleVector;
+//	typedef std::vector<IntVector> DoubleMatrix;
+	
+	
+//	DynamicVector prior;
+//	DynamicVector posterior;
+//	DynamicVector likelihood;
+	
+	DynamicVector testVector;	
+//	DynamicVector prior;
+	
+	float prior [ARRAY_SIZE];
+	float posterior [ARRAY_SIZE];
+	float likelihood [ARRAY_SIZE];	
+	float tempPosteriorArray[ARRAY_SIZE];
+	
+	float decayNoiseArray[ARRAY_SIZE];
+	float decayNoiseStdDev, decayNoiseAmount;
+	
+	float likelihoodMean, likelihoodStdDev, likelihoodNoise;
+	float maximumTest, posteriorDecayRate, maximumValue;
+	float eighthNoteProportion, earlySixteenthNoteProportion, lateSixteenthNoteProportion ;
+	float maximumEstimate, maximumIndex, integratedEstimate;
+	double standardDeviation;
+	
+private:
+};
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/DynamicVector.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,273 @@
+/*
+ *  DynamicVector.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 18/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+
+#include "DynamicVector.h"
+
+DynamicVector::DynamicVector(){
+	length = 0;
+	arraySize = 0;
+	maximumValue = 0;
+	MAPestimate = 0;
+	offset = 0;
+	scalar = 1;
+	integratedEstimate = length/2;
+	
+	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){
+	if (dynamicVec.length == length){
+		for (int i = 0;i < length;i++)
+			array[i] = dynamicVec.array[i];
+	}
+	else{
+		printf("CANNOT COPY VECTORS OF NON SAME LENGTH!!\n");
+	}
+}
+
+void DynamicVector::createVector(int len){
+	array.clear();
+	for (int i = 0; i < len;i++){
+		array.push_back(0);
+	}
+	length = len;
+	arraySize = array.size();
+	integratedEstimate = length/2;
+}
+
+
+double DynamicVector::getMaximum(){
+	int i;
+	double max = 0;
+	for (i=0;i < length;i++){	
+		if (array[i] > max){
+			max = array[i];
+			MAPestimate = i;
+		}
+	}
+	maximumValue = max;
+	return max;
+}
+
+double DynamicVector::getIntegratedEstimate(){
+	//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;
+	}
+	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;
+}
+
+void DynamicVector::renormalise(){
+	double tmpMax = getMaximum();
+	if (tmpMax > 0){
+//	printf("renormalise : max is %f and size is %i\n", tmpMax, arraySize);		
+		for (int i = 0;i < array.size();i++)
+			array[i] /= tmpMax;
+
+	}
+	//printArray();
+}
+
+void DynamicVector::doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo){
+
+	for (int i = 0;i < arrayOne.length;i++)
+		array[i] = arrayOne.array[i] * arrayTwo.array[i];
+}
+
+
+void DynamicVector::printArray(){
+	for (int i = 0;i < arraySize;i++){
+		printf("[%i] = %f\n", i, array[i]);
+	}
+}
+
+void DynamicVector::translateDistribution(int translationIndex){
+	int tmpIndex;
+	DoubleVector tmpArray;
+	int i;
+
+	for (i=0;i < arraySize;i++){
+		tmpArray.push_back(array[i]);
+	}
+	//translate values
+	for (i=0;i < arraySize;i++){
+		tmpIndex = (i + translationIndex + arraySize)%arraySize;
+		array[tmpIndex] = tmpArray[i]; 
+	}
+	tmpArray.clear();
+	//now delete tmp array
+}
+
+void DynamicVector::addGaussianShape(const double& mean, const double& StdDev, double factor){
+	
+	int i;
+	double std_dev_factor = (2*StdDev*StdDev);
+	factor *= (1/(StdDev*sqrt(2*PI)));
+	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);
+}
+
+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;
+
+	for (i= max(0., (double)(mean - width));i < min((mean+width), (double)array.size());i++){
+		array[i] += factor * abs(i - mean) / mean;		
+	}
+
+}
+
+void DynamicVector::addConstant(const double& value){
+	for (int i=0;i<array.size();i++){
+		array[i] += value;
+	}
+}
+
+
+void DynamicVector::addToIndex(const int& index, const double& constant){
+	array[index] += constant;
+}
+
+
+double DynamicVector::getIndexInRealTerms(const int& index){
+	if (index < arraySize)
+		return (offset + scalar*index);
+	else
+		return 0;
+}
+
+double DynamicVector::getRealTermsAsIndex(double value){
+	value -= offset;
+	value /= scalar;
+	
+	return value;
+	
+}
+
+double DynamicVector::getValueAtMillis(const double& millis){
+	
+	int index = round(getRealTermsAsIndex(millis));
+		if (index >= 0 && index < length)
+			return array[index];
+		else
+			return 0;
+}
+
+void DynamicVector::drawVector(const int& minIndex, const int& maxIndex){
+
+		
+		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
+		double screenHeight = (double) ofGetHeight();
+		double maxVal = getMaximum();
+	
+		int startInt = max(1,minIndex+1);
+		int endInt = min(maxIndex, (int)array.size());
+		double heightConstant = screenHeight / maxVal;
+		int lastHeightPixel = heightConstant * (maxVal - array[startInt-1]);
+		int newHeightPixel;
+		for (int i = startInt;i < endInt;i++){
+			newHeightPixel = (int) heightConstant * (maxVal - array[i]);
+			ofLine (stepSize*(i-1), lastHeightPixel, stepSize*i, newHeightPixel);
+			lastHeightPixel = newHeightPixel;
+		}
+	
+}
+
+
+void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex){
+	//constrain the height and width
+	
+	double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin 
+	double screenHeight = ofGetHeight();
+	double maxVal = getMaximum();
+
+	//OPTIMIZE!! XXX could just add stepsize each time
+	//not add minindex each time
+	int i = max(1,minIndex+1);
+//	ofDrawBitmapString("i = "+ofToString(i)+"  :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640);
+	
+	while ((minScreenIndex + stepSize*(i-minIndex)) < 0)
+		i++;//only draw what is on the screen
+	
+	for ( ; i < min(maxIndex+1, (int)array.size());i++){
+		ofLine (minScreenIndex + (stepSize*(i-minIndex-1)), screenHeight * (1 - array[i-1] / maxVal), 
+				minScreenIndex + (stepSize*(i-minIndex)),	 screenHeight * (1 - array[i] / maxVal) );
+		
+	}
+	
+	ofLine(minScreenIndex, screenHeight, minScreenIndex, screenHeight/2);
+	ofLine(maxScreenIndex, screenHeight, maxScreenIndex, screenHeight/2);
+	
+//	ofDrawBitmapString(ofToString(stepSize, 2)+"  "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/DynamicVector.h	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,67 @@
+/*
+ *  DynamicVector.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 18/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+//OPTIMIZE CONSTRAINED VECTOR
+
+#include "stdlib.h"
+#include "ofMain.h"
+
+#ifndef _DYNAMIC_VECTOR
+#define _DYNAMIC_VECTOR
+#define GAUSSIAN_LOOKUP_LENGTH 1000000
+
+class DynamicVector{
+public:
+	DynamicVector();
+
+	void createVector(int len);
+	void renormalise();
+	void translateDistribution(int translationIndex);
+	typedef std::vector<double> DoubleVector;
+	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;
+	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);
+
+	void addConstant(const double& value);
+	void addGaussianShape(const double& mean, const double& stddev, double factor);
+	void addTriangularShape(double mean, double width, double factor);
+	void addToIndex(const int& index, const double& constant);
+	
+	void doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo);
+		
+	double getIndexInRealTerms(const int& index);
+	double getRealTermsAsIndex(double value);
+	double getValueAtMillis(const double& millis);
+	
+	void printArray();
+	void zero();
+	
+	void copyFromDynamicVector(const DynamicVector& dynamicVec);
+	
+	//variables
+	int length, arraySize;
+	double maximumValue;
+	int MAPestimate;
+	
+	double offset;
+	double scalar;//each array point is this much of the quantity
+	//i.e. array[index] contributes to (offset + scalar*index) in real terms
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/drawMidiNotes.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,87 @@
+/*
+ *  drawMidiNotes.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "drawMidiNotes.h"
+
+drawMidiNotes::drawMidiNotes(){
+
+	
+	ticksPerScreen = 8000;
+	tickLocation = 0;
+	pulsesPerQuarternote = 240;
+	noteArrayIndex = 0;
+	noteMinimum = 30;
+	noteMaximum = 96;
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();
+	noteHeight = screenHeight / (float)(noteMaximum - noteMinimum);
+}
+
+void drawMidiNotes::reset(){
+	noteArrayIndex = 0;
+	tickLocation = 0;
+	lastPeriodUpdateTime = ofGetElapsedTimeMillis();
+	
+}
+
+void drawMidiNotes::updatePlayPosition(){
+	double timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;
+	//this is time diff in milliseconds
+	//then we have 
+	double quarterNoteIntervals = (timeDifference / period);
+	tickLocation = quarterNoteIntervals * pulsesPerQuarternote; 
+
+}
+
+void drawMidiNotes::drawFile(const IntMatrix& noteOnMatrix){
+	int size = noteOnMatrix.size();
+	if (size > 0){
+
+		int numberOfScreensIn = tickLocation / ticksPerScreen;
+		
+	while (noteArrayIndex < noteOnMatrix.size() && tickLocation > noteOnMatrix[noteArrayIndex][0] )
+		noteArrayIndex++;
+	
+	while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < noteOnMatrix[noteArrayIndex][0])
+		noteArrayIndex--;
+		
+		//need to start where we currently are in file
+		int maxNoteIndexToPrint	= noteArrayIndex;
+		int minNoteIndexToPrint = noteArrayIndex;
+		
+		
+		while (maxNoteIndexToPrint < noteOnMatrix.size() && noteOnMatrix[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen )
+			maxNoteIndexToPrint++;
+		
+		while (minNoteIndexToPrint > 0 && minNoteIndexToPrint < size && noteOnMatrix[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)
+			minNoteIndexToPrint--;
+		
+		
+		for (int tmpIndex = minNoteIndexToPrint;tmpIndex < maxNoteIndexToPrint;tmpIndex++){
+		int xLocation = (float)(noteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*screenWidth/(float)ticksPerScreen;
+			int duration = (float)(noteOnMatrix[tmpIndex][3]*screenWidth)/(float)ticksPerScreen;
+			
+			
+		int yLocation = screenHeight - ((noteOnMatrix[tmpIndex][1] - noteMinimum )*screenHeight/ (float)(noteMaximum - noteMinimum));						 
+		ofRect(xLocation,yLocation, duration,  noteHeight);
+		
+		}
+		
+			int xLocation = (float)(tickLocation - numberOfScreensIn*ticksPerScreen)*screenWidth/(float)ticksPerScreen;
+		ofLine(xLocation, 0, xLocation, screenHeight);
+	
+	//	if (noteArrayIndex < size )
+	//		printf("tick %i :: note array :%i: %i\n", tickLocation, noteArrayIndex, noteOnMatrix[noteArrayIndex][0]);
+	//	else
+	//		printf("end of file\n");
+
+		
+	}	
+		
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/drawMidiNotes.h	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,42 @@
+/*
+ *  drawMidiNotes.h
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+
+#include "ofMain.h"
+
+class drawMidiNotes{
+public:
+	drawMidiNotes();
+	void updatePlayPosition();
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	
+	DoubleMatrix beatPeriodMatrix;
+	
+	typedef std::vector<int> IntVector;
+	typedef std::vector<IntVector> IntMatrix;
+	
+	void drawFile(const IntMatrix& noteOnMatrix);
+	void reset();
+	
+	int ticksPerScreen;
+	int tickLocation;
+	int noteArrayIndex;
+	
+	int noteMinimum, noteMaximum;
+	int screenWidth, screenHeight;
+	float noteHeight;
+	float tempo;
+	double period;
+	int pulsesPerQuarternote;
+	double lastPeriodUpdateTime;
+					 
+	
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/main.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,25 @@
+#include "ofMain.h"
+#include "testApp.h"
+#include "ofAppGlutWindow.h"
+#include "ofxArgs.h"
+
+//========================================================================
+int main(int argc, char *argv[]){
+	ofxArgs* args = new ofxArgs(argc, argv);
+	
+	if (argc > 0){
+		cout << "MIDI FOLLOW (" << argc << ")  arg[1] is " << argv[1] << endl;
+	}
+	
+    ofAppGlutWindow window;
+	ofSetupOpenGL(&window, 1024,768, OF_WINDOW);			// <-------- setup the GL context
+
+	// this kicks off the running of my app
+	// can be OF_WINDOW or OF_FULLSCREEN
+	// pass in width and height too:
+	
+	ofRunApp(new testApp(args));
+	delete args;
+
+}
+
--- a/hackday/midiEventHolder.cpp	Sun Dec 04 14:30:33 2011 +0000
+++ b/hackday/midiEventHolder.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -20,7 +20,7 @@
 	runningInRealTime = true;
 	bayesStruct.realTimeMode = &runningInRealTime;
 	
-	minimumMatchSpeed = 0.2;
+	minimumMatchSpeed = 0.5;
 	maximumMatchSpeed = 2.0;
 	minimumTimeIntervalForTempoUpdate = 150;
 	
@@ -49,7 +49,7 @@
 	
 	speedPriorValue = 1.0;
 	
-	matchWindowWidth = 12000;//window size for matching in ms 
+	matchWindowWidth = 8000;//window size for matching in ms 
 	
 	bayesStruct.resetSize(matchWindowWidth);
 	bayesStruct.setPositionDistributionScalar(1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/musescore info.txt	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,10 @@
+http://musescore.org/en/project/blacknotes
+
+to uncolor
+
+drag to muse nightly -> plugins
+
+activate coloronenote in prefs
+
+restart mus sc
+
--- a/hackday/testApp.cpp	Sun Dec 04 14:30:33 2011 +0000
+++ b/hackday/testApp.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -413,6 +413,7 @@
 		sendMeasureToMuseScore();
 		sendBlackNotes();
 		lastScoreIndexSent = 0;
+		performanceRating = 0;
 		
 	}