diff src/TempoFollower.cpp @ 20:4f6006cac9de

added evaluation of recorded tempo, holding of this data, drawing of recorded and playing tempo estimates
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sun, 12 Feb 2012 00:48:07 +0000
parents 1a62561bd72d
children 9806a4f22fd0
line wrap: on
line diff
--- a/src/TempoFollower.cpp	Thu Feb 09 18:09:34 2012 +0000
+++ b/src/TempoFollower.cpp	Sun Feb 12 00:48:07 2012 +0000
@@ -10,6 +10,10 @@
 #include "TempoFollower.h"
 
 TempoFollower::TempoFollower(){
+	
+	
+	
+	
 	maximumTempoInterval = 600;
 	minimumTempoInterval = 200;
 	tempoArraySize = maximumTempoInterval - minimumTempoInterval;;
@@ -27,13 +31,31 @@
 	tempoPrior.scalar = 1;
 	tempoPosterior.scalar = 1;
 	tempoLikelihood.scalar = 1;
+
+	intervalsToTest[0] = 1;
+	intervalsToTest[1] = 2;
+	intervalsToTest[2] = 4;
+	intervalsToTest[3] = 8;
+	intervalsToTest[4] = 16;
+	
+	setUpEventTimeMatrix();
 }
 
+void TempoFollower::zero(){
+	eventTimes.clear();
+	tempoIntervals.clear();
+	divisions.clear();
+	tempo.clear();
+	globalTempo.clear();
+	globalTempoTimes.clear();
+	setUpEventTimeMatrix();
+}
 
 void TempoFollower::reset(){
 
 	tempoPrior.zero();
 	tempoPosterior.addConstant(1);
+
 }
 
 
@@ -44,6 +66,13 @@
 		
 		DoubleMatrix m;	
 		tempoIntervals.push_back(m);
+		
+		IntMatrix h;
+		divisions.push_back(h);
+		
+		DoubleVector d;
+		tempo.push_back(d);
+		
 	}
 	
 	//[channel][index]
@@ -60,6 +89,13 @@
 }
 
 
+void TempoFollower::printTempoTimes(){
+
+	for (int i = 0;i < globalTempo.size();i++){
+		printf("Time %i : tempo %f\n", globalTempoTimes[i], globalTempo[i]);
+	}
+}
+
 void TempoFollower::updateTempo(const int& channel, const int& timeIn){
 	
 	eventTimes[channel].push_back(timeIn);
@@ -70,27 +106,33 @@
 	int recentIndex = eventTimes[channel].size()-1;
 	
 	DoubleVector d;
-	
+	IntVector div;
 	int recentEvent = eventTimes[channel][recentIndex];
 	
 	for (int i = 1;i < eventTimes[channel].size() && interval < intervalLimit;i++){
 		interval = eventTimes[channel][recentIndex] - eventTimes[channel][recentIndex - i];
 		
-		if (testTempoInterval(channel, interval, d))
-			printf("channel %i interval %i at division 1 == tempo update %i\n", channel, interval, interval);
-		
-		for (double divisionInEighthNotes = 2.0;divisionInEighthNotes < 9.0;divisionInEighthNotes+=2){
+		for (int k = 0;k < 3;k++){
 			
+			double divisionInEighthNotes = intervalsToTest[k];
 			double testInterval = interval / divisionInEighthNotes;
-			if (testTempoInterval(channel, testInterval, d))
+			if (testTempoInterval(channel, testInterval, d)){
 				printf("channel %i interval %i at division %.0f == tempo update %f\n", channel, interval, divisionInEighthNotes, testInterval);
-			
+				div.push_back((int)divisionInEighthNotes);
+			}
 		}
 	}
 	
 	(tempoIntervals[channel]).push_back(d);
+	(divisions[channel]).push_back(div);
 	updateTempoDistribution(d);
 	
+	tempo[channel].push_back(playingTempo);
+	
+	globalTempo.push_back(playingTempo);
+	globalTempoTimes.push_back(timeIn);
+	
+	
 }
 
 
@@ -106,16 +148,19 @@
 
 void TempoFollower::updateTempoDistribution(const DoubleVector& d){
 	double tempoLikelihoodToNoiseRatio = 0.8;
+	tempoLikelihoodStdDev = 4;
+	
 	tempoLikelihood.zero();
 	double amount = tempoLikelihoodToNoiseRatio/d.size();
 	for (int i = 0;i < d.size();i++){
-		tempoLikelihood.addGaussianShapeFromRealTime(d[i], 10, amount);
+		tempoLikelihood.addGaussianShapeFromRealTime(d[i], tempoLikelihoodStdDev, amount);
 	}
 	tempoLikelihood.addConstant(0.1*(1-tempoLikelihoodToNoiseRatio));
 	calculatePosterior();
-	
 	tempoPosterior.renormalise();
 	playingTempo = tempoPosterior.getIndexInRealTerms(tempoPosterior.getMAPestimate());
+	
+	
 }
 
 
@@ -130,5 +175,25 @@
 void TempoFollower::drawTempoArray(ofxWindowRegion& window){
 	ofSetColor(150,0,250);
 	tempoPosterior.drawConstrainedVector(0, tempoArraySize, 0, ofGetWidth(), window);
+	
+	ofSetColor(150,150,150);
+	tempoLikelihood.drawConstrainedVector(0, tempoArraySize, 0, ofGetWidth(), window);
+	
+	
 	ofDrawBitmapString("tempo "+ofToString(playingTempo), window.x+ 20, window.y + 40);
+	
+
+	for (int channel = 0;channel < 3;channel+=2){
+		int index = tempoIntervals[channel].size()-1;
+		
+		for (int i = 0;i < 9 && index - i>=0 ;i++){
+			for (int j = 0;j < tempoIntervals[channel][index - i].size();j++){
+				ofSetColor(channel*125, 0, 250);
+				ofCircle(window.x+((tempoIntervals[channel][index - i][j] - minimumTempoInterval)*window.width)/tempoArraySize, window.y+6+(window.height*i/9.0), 4);
+				ofSetColor(255,255,255);
+				ofDrawBitmapString(ofToString(divisions[channel][index-i][j]), (window.x+((tempoIntervals[channel][index - i][j] - minimumTempoInterval)*window.width)/tempoArraySize)-3, window.y+8+(window.height*i/9.0));
+			}
+		}
+	}
 }
+