Mercurial > hg > multitrack-audio-matcher
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)); + } + } + } } +