Mercurial > hg > multitrack-audio-matcher
changeset 45:d23685b9e766
Fixed the alignment error caluculations and added histogram plotting
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Tue, 08 May 2012 21:53:11 +0100 |
parents | 73fbbc92fdfb |
children | ba36a1721538 |
files | annotationCalculatorSrc/BeatAnnotationReader.cpp annotationCalculatorSrc/BeatAnnotationReader.h annotationCalculatorSrc/Histogram.cpp annotationCalculatorSrc/Histogram.h annotationCalculatorSrc/MatchMultitrackAnnotationReader.cpp annotationCalculatorSrc/MatchMultitrackAnnotationReader.h annotationCalculatorSrc/PlotTools.cpp annotationCalculatorSrc/PlotTools.h annotationCalculatorSrc/testApp.cpp annotationCalculatorSrc/testApp.h dev notes.txt src/AccompanimentSynchroniser.cpp src/AudioEventMatcher.cpp src/AudioEventMatcher.h src/testApp.cpp |
diffstat | 15 files changed, 494 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/annotationCalculatorSrc/BeatAnnotationReader.cpp Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/BeatAnnotationReader.cpp Tue May 08 21:53:11 2012 +0100 @@ -130,3 +130,91 @@ alignmentTimes.push_back(playedAlignTimes); } + +double BeatAnnotationReader::calculateMedianError(const DoubleVector& liveBeatTimes, const DoubleVector& groundTruthAlignment){ + //use our alignment Times to calculate error rekative to these ground truth times + errors.clear(); + + int alignmentLiveIndex = 0; + for (int i = 0;i < liveBeatTimes.size() && i < groundTruthAlignment.size();i++){ + double time = liveBeatTimes[i]; + + //now need alignment at this time + //recorded, i.e. MAP estimate alignment, is alignmentTimes[1]; + //getAlignmentErrorAtTime(time); + + while (alignmentLiveIndex < alignmentTimes[0].size() && alignmentTimes[0][alignmentLiveIndex] < time) { + alignmentLiveIndex++; + } + + while (alignmentLiveIndex > 0 && alignmentTimes[0][alignmentLiveIndex] > time) { + alignmentLiveIndex--; + } + //now is less + double result = alignmentTimes[1][alignmentLiveIndex]; + + double fractionOfNext = 0; + if (alignmentLiveIndex < alignmentTimes[0].size() + 1 && time > alignmentTimes[0][alignmentLiveIndex]){ + double numerator = time - alignmentTimes[0][alignmentLiveIndex]; + double denom = alignmentTimes[0][alignmentLiveIndex+1] - alignmentTimes[0][alignmentLiveIndex]; + //printf("num %f / demon %f \n", numerator, denom); + fractionOfNext = (time - alignmentTimes[0][alignmentLiveIndex])/(alignmentTimes[0][alignmentLiveIndex+1] - alignmentTimes[0][alignmentLiveIndex]); + result += fractionOfNext * (alignmentTimes[1][alignmentLiveIndex+1] - alignmentTimes[1][alignmentLiveIndex]); + } + double error = result - groundTruthAlignment[i];//error relative to ground truth + error *= 1000.0;//now in ms + printf("live time %.4f align time %f ground truth %.3f error %.1f\n", time, result, groundTruthAlignment[i], error); + // printf("time %.4f align time %f frac %.3f albelow %.4f above %.4f error %.2f\n", time, result, fractionOfNext, alignmentTimes[0][alignmentLiveIndex], alignmentTimes[0][alignmentLiveIndex+1], error); + + // printf("aligns to above %.4f below %.4f\n", alignmentTimes[1][alignmentLiveIndex+1], alignmentTimes[1][alignmentLiveIndex]); + + errors.push_back(error); + } + +} + + + +double BeatAnnotationReader::calculateMedianError(const DoubleVector& liveBeatTimes, const DoubleVector& groundTruthAlignment, const DoubleVector& alignmentLiveTimes, const DoubleVector& alignmentRehearsalTimes){ + //use our alignment Times to calculate error rekative to these ground truth times + errors.clear(); + + int alignmentLiveIndex = 0; + for (int i = 0;i < liveBeatTimes.size() && i < groundTruthAlignment.size();i++){ + double time = liveBeatTimes[i]; + + //now need alignment at this time + //recorded, i.e. MAP estimate alignment, is alignmentRehearsalTimes; + //getAlignmentErrorAtTime(time); + + while (alignmentLiveIndex < alignmentLiveTimes.size() && alignmentLiveTimes[alignmentLiveIndex] < time) { + alignmentLiveIndex++; + } + + while (alignmentLiveIndex > 0 && alignmentLiveTimes[alignmentLiveIndex] > time) { + alignmentLiveIndex--; + } + //now is less + double result = alignmentRehearsalTimes[alignmentLiveIndex]; + + double fractionOfNext = 0; + if (alignmentLiveIndex < alignmentLiveTimes.size() + 1 && time > alignmentLiveTimes[alignmentLiveIndex]){ + double numerator = time - alignmentLiveTimes[alignmentLiveIndex]; + double denom = alignmentLiveTimes[alignmentLiveIndex+1] - alignmentLiveTimes[alignmentLiveIndex]; + //printf("num %f / demon %f \n", numerator, denom); + fractionOfNext = (time - alignmentLiveTimes[alignmentLiveIndex])/(alignmentLiveTimes[alignmentLiveIndex+1] - alignmentLiveTimes[alignmentLiveIndex]); + result += fractionOfNext * (alignmentRehearsalTimes[alignmentLiveIndex+1] - alignmentRehearsalTimes[alignmentLiveIndex]); + } + double error = result - groundTruthAlignment[i];//error relative to ground truth + error *= 1000.0;//now in ms + printf("live time %.4f align time %f ground truth %.3f error %.1f\n", time, result, groundTruthAlignment[i], error); + // printf("time %.4f align time %f frac %.3f albelow %.4f above %.4f error %.2f\n", time, result, fractionOfNext, alignmentLiveTimes[alignmentLiveIndex], alignmentLiveTimes[alignmentLiveIndex+1], error); + + // printf("aligns to above %.4f below %.4f\n", alignmentRehearsalTimes[alignmentLiveIndex+1], alignmentRehearsalTimes[alignmentLiveIndex]); + + errors.push_back(error); + } + +} + +
--- a/annotationCalculatorSrc/BeatAnnotationReader.h Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/BeatAnnotationReader.h Tue May 08 21:53:11 2012 +0100 @@ -22,6 +22,7 @@ public: typedef std::vector<double> DoubleVector; DoubleVector beatTimes; + DoubleVector errors; typedef std::vector<DoubleVector> DoubleMatrix; DoubleMatrix alignmentTimes; @@ -30,5 +31,12 @@ void printBeatTimes(); void readInMultiAlignmentFile(std::string pathName); + + +// typedef vector<DoubleVector> DoubleMatrix; + double calculateMedianError(const DoubleVector& liveBeatTimes, const DoubleVector& groundTruthAlignment); + double calculateMedianError(const DoubleVector& liveBeatTimes, const DoubleVector& groundTruthAlignment, const DoubleVector& alignmentLiveTimes, const DoubleVector& alignmentRehearsalTimes); + + //double getAlignmentErrorAtTime(const double& liveTime); }; #endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annotationCalculatorSrc/Histogram.cpp Tue May 08 21:53:11 2012 +0100 @@ -0,0 +1,84 @@ +/* + * Histogram.cpp + * annotationResultCalculator + * + * Created by Andrew on 08/05/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + +#include "Histogram.h" + +Histogram::Histogram(){ +screenHeight = ofGetHeight(); +} + +void Histogram::createHistogram(const int& binWidthIn, const int& numberofBinsIn, DoubleVector& data){ + numberofBins = numberofBinsIn; + binWidth = binWidthIn; + histogram.clear(); + histogram.assign(numberofBins, 0); + maximum = 0; + double binPoint; + int bin = 0; + for (int i = 0;i < data.size();i++){ + //find which bin it falls into. + //5 bins, width is 10 + //then we start around zero for the 5+1/2 th, i.e. 3rd bin + //zero is the 5/2 th pt + + bin = 0; + binPoint = -1.0 * binWidth * ((double)numberofBins/2); + + if (data[i] >= binPoint){//i.e. falls inside + while (data[i] > (binPoint + binWidth) && bin < numberofBins) { + //printf("data pt %f bin %i binPt %.1f\n", data[i], bin, binPoint); + binPoint += binWidth; + bin++; + } + + printf("data pt %f bin %i binPt %.1f\n", data[i], bin, binPoint); + + if (data[i] <= binPoint + binWidth){//in case outside range + histogram[bin]++; + } + } + } + + for (int k = 0; k < histogram.size();k++){ + + if (histogram[k] > maximum) + maximum = histogram[k]; + + printf("HISTO[%i] = %i\n", k, histogram[k]); + } + + +} + +void Histogram::plotHistogram(){ + plotHistogram(maximum); +} + +void Histogram::plotHistogram(const double& maxHeight){ + + double width = ofGetWidth(); + double height = ofGetHeight(); + screenHeight = ofGetHeight(); + if (numberofBins > 0 && maxHeight > 0){ + width /= numberofBins; + height /= maxHeight; + + for (int i = 0;i < numberofBins;i++){ + ofRect(i * width, getY(histogram[i]*height), width, histogram[i]*height); + } + + } + +} + + +int Histogram::getY(const int& y){ + return screenHeight - y; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annotationCalculatorSrc/Histogram.h Tue May 08 21:53:11 2012 +0100 @@ -0,0 +1,36 @@ +/* + * Histogram.h + * annotationResultCalculator + * + * Created by Andrew on 08/05/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + + + +#ifndef HISTOGRAM +#define HISTOGRAM + +#include "ofMain.h" + +class Histogram{ +public: + Histogram(); + typedef std::vector<double> DoubleVector; + typedef std::vector<int> IntVector; + IntVector histogram; + + void createHistogram(const int& binWidth, const int& numberofBins, DoubleVector& data); + void plotHistogram(); + void plotHistogram(const double& maxHeight); + + int numberofBins; + int binWidth; + + double maximum; + + int getY(const int& y); + int screenHeight; +}; +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annotationCalculatorSrc/MatchMultitrackAnnotationReader.cpp Tue May 08 21:53:11 2012 +0100 @@ -0,0 +1,69 @@ +/* + * MatchMultitrackAnnotationReader.cpp + * annotationResultCalculator + * + * Created by Andrew on 08/05/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + +#include "MatchMultitrackAnnotationReader.h" + + + +void MatchMultitrackAnnotationReader::readInMatchFile(std::string& pathName){ + + // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv" + matchData.clear(); + matchLiveTimes.clear(); + matchRehearsalTimes.clear(); + + // printf("MATCH : READ FILE %s\n", pathName.c_str()); + ifstream file ( pathName.c_str()); + string value, tmpLine; + stringstream iss; + int count = 0; + MatchNotation n; + while ( file.good() ) + { + getline(file, tmpLine); + iss << tmpLine; + // printf("tmp line %s\n", tmpLine.c_str()); + while(getline ( iss, value, '\t' )){ // read a string until next comma: http://www.cplusplus.com/reference/string/getline/ + // cout << string( value, 1, value.length()-2 ); // display value removing the first and the last character from it + // printf("line:%s\n", value.c_str()); + string::size_type start = value.find_first_not_of(" ,\t\v\n"); + string firstpart = value.substr(start, string::npos); + string::size_type end = firstpart.find_first_of(" ,\t\v\n"); + string part = firstpart.substr(0, end); + string secondpart = firstpart.substr(end, string::npos); + start = secondpart.find_first_not_of(" ,\t\v\n"); + secondpart = secondpart.substr(start , string::npos); + // printf("part:%s,%s\n", part.c_str(), secondpart.c_str()); + MatchNotation n; + n.firstTime = atof(part.c_str()); + n.secondTime = atof(secondpart.c_str()); + matchLiveTimes.push_back(atof(part.c_str())); + matchRehearsalTimes.push_back(atof(secondpart.c_str())); + + matchData.push_back(n); + }//end while reading line + iss.clear(); + + + }//end while + + // printAnnotations(); + // printf("There are %i MATCH annotations\n", (int)matchData.size()); + +} + +void MatchMultitrackAnnotationReader::printAnnotations(){ + //rwcAnnotations.size() + for (int i = 0;i < min(200, (int)matchData.size());i++){ + printf("MATCH audio times %f, midi played time %f \n", + matchData[i].firstTime, + matchData[i].secondTime); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annotationCalculatorSrc/MatchMultitrackAnnotationReader.h Tue May 08 21:53:11 2012 +0100 @@ -0,0 +1,41 @@ +/* + * MatchMultitrackAnnotationReader.h + * annotationResultCalculator + * + * Created by Andrew on 08/05/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + + + +#ifndef MATCH_MULTITRACK_ANNOTATIONS +#define MATCH_MULTITRACK_ANNOTATIONS + +#include "ofMain.h" + +#include <iostream> +#include <fstream> +using namespace std; + +struct MatchNotation { + + float firstTime; + float secondTime; +}; + +class MatchMultitrackAnnotationReader{ +public: + //matchAnnotations(); + + void readInMatchFile(std::string& pathName); + //~Annotations(); + void printAnnotations(); + vector<MatchNotation> matchData; + + typedef vector<double> DoubleVector; + DoubleVector matchLiveTimes; + DoubleVector matchRehearsalTimes; + +}; +#endif \ No newline at end of file
--- a/annotationCalculatorSrc/PlotTools.cpp Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/PlotTools.cpp Tue May 08 21:53:11 2012 +0100 @@ -10,7 +10,7 @@ #include "PlotTools.h" PlotTools::PlotTools(){ - + plotPoints = true; } void PlotTools::plotVector(const DoubleVector& d){ @@ -52,22 +52,26 @@ void PlotTools::plotTwoVectors(const DoubleVector& d, const DoubleVector& h){ //just picks the min and max of each and plots with these as the width and height ranges. plotTwoVectors(d, h, *(std::min_element( d.begin(), d.end() )),*(std::max_element( d.begin(), d.end()) ), - *(std::min_element( h.begin(), h.end() )),*(std::max_element( h.begin(), h.end()) ) ); + *(std::min_element( h.begin(), h.end() )),*(std::max_element( h.begin(), h.end()) ), false); } -void PlotTools::plotTwoVectors(const DoubleVector& d, const DoubleVector& h, const double& xStart, const double& xEnd, const double& yStart, const double& yEnd){ +void PlotTools::plotTwoVectors(const DoubleVector& d, const DoubleVector& h, const double& xStart, const double& xEnd, const double& yStart, const double& yEnd, const bool drawAxes){ // printf("%f %f %f %f\n", xStart, xEnd, yStart, yEnd); int startX, endX, startY, endY; startX = 0; while (d[startX] < xStart) startX++; + startX--; + startX = max(0, (int) round(xStart)); endX = (int)d.size()-1; while (d[endX] > xEnd) { endX--; } + if (endX < d.size()-1) + endX++; //startX and endX are in terms of indices now... @@ -89,12 +93,19 @@ double newYindex = (h[i] - yStart) * heightRatio; double newXindex = (int)(xRatio * (d[i] - xStart)); ofLine(xIndex, getY(yIndex), newXindex, getY(newYindex)); + + + if (plotPoints) + ofCircle(newXindex, getY(newYindex), 1);//then plots points too + xIndex = newXindex; yIndex = newYindex; }//end for //do axis + if (drawAxes){ + int wIndex, hIndex; int numberOfPts = 5; for (int x = 1; x < numberOfPts;x++){ @@ -121,6 +132,7 @@ ofLine(0, markIndex, 10, markIndex); ofDrawBitmapString(ofToString(h[hIndex], 1), 2, markIndex); }//end for y for axis + }//end draw axes }//end if yRange > 0 @@ -130,8 +142,12 @@ } + + + int PlotTools::getY(const int& y){ return screenHeight - y; } +
--- a/annotationCalculatorSrc/PlotTools.h Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/PlotTools.h Tue May 08 21:53:11 2012 +0100 @@ -24,10 +24,14 @@ void plotVector(const DoubleVector& d, const double& xStart, const double& xEnd, const double& yStart, const double& yEnd); void plotTwoVectors(const DoubleVector& d, const DoubleVector& h); - void plotTwoVectors(const DoubleVector& d, const DoubleVector& h, const double& xStart, const double& xEnd, const double& yStart, const double& yEnd); + void plotTwoVectors(const DoubleVector& d, const DoubleVector& h, const double& xStart, const double& xEnd, const double& yStart, const double& yEnd, const bool drawAxes); double screenHeight; double screenWidth; int getY(const int& y); + bool plotPoints; + + + }; #endif \ No newline at end of file
--- a/annotationCalculatorSrc/testApp.cpp Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/testApp.cpp Tue May 08 21:53:11 2012 +0100 @@ -4,25 +4,49 @@ void testApp::setup(){ ofBackground(255); - std::string path = "../../../data/marbleArch_6_beats.txt"; + std::string path = "../../../data/marbleArch_4_beats.txt"; +// path = "../../../data/marbleArchKick_take4.txt"; + beatReader.readInBeatsFile(path); GroundTruth.push_back(beatReader.beatTimes);//so we have our first file list of beats //now get the second file beat list - path = "../../../data/marbleArch_4_beats.txt";//just the same one for the mo... + path = "../../../data/marbleArch_6_beats.txt";//just the same one for the mo... +// path = "../../../data/marbleArchKick_take6.txt";//annotated kick tracks beatReader.readInBeatsFile(path); GroundTruth.push_back(beatReader.beatTimes);//so we have our first file list of beats //so GroundTruth[0] is the DoubleVector of file 1 beats + //this is the Live file - i.e. played along //i.e. GT[0][0] - first, GT[0][1] second and so on - path = "../../../data/marbleArchloaded6_live4.txt"; +// path = "../../../data/marbleArchloaded6_live4.txt"; + path = "../../../data/MarbleArch_live4_reh6_output.txt"; + path = "../../../data/marbleArch_take4_to_take6_new_output.txt"; + path = "../../../data/MarbleArch_live4_reh6_newOutput.txt"; //Then we need to know where our alignment path has gone and projected these positions to be + //this is the rehearsal file that was analysed //so we need to load an alignment path //then calculate the error histogram etc beatReader.readInMultiAlignmentFile(path); + beatReader.calculateMedianError(GroundTruth[0], GroundTruth[1], beatReader.alignmentTimes[0], beatReader.alignmentTimes[1]); + + histogramWidth = 10; + histogramBinNumber = 25; + + matchPath = "../../../data/MatchAlignments/marbleArchlive4_reh6_match_OB.out"; + matchNotations.readInMatchFile(matchPath); + multiHistogram.createHistogram(histogramWidth, histogramBinNumber, beatReader.errors); + + printf("\n\nGET ERRORS FOR MATCH\n\n"); + beatReader.calculateMedianError(GroundTruth[0], GroundTruth[1], matchNotations.matchLiveTimes, matchNotations.matchRehearsalTimes); + matchHistogram.createHistogram(histogramWidth, histogramBinNumber, beatReader.errors); + + screenToDraw = 1; + + xPlotMin = 0; xPlotMax = 40; yPlotMin = 0; @@ -36,19 +60,42 @@ //-------------------------------------------------------------- void testApp::draw(){ + switch (screenToDraw) { + case 0: + drawAlignmentVectors(); + break; + case 1: + ofSetColor(0,0,255); + multiHistogram.plotHistogram(); + break; + case 2: + ofSetColor(0,255,0); + matchHistogram.plotHistogram(); + break; + } +} + +void testApp::drawAlignmentVectors(){ + ofSetColor(0,0,0); -// plotter.plotVector(beatReader.beatTimes); + // plotter.plotVector(beatReader.beatTimes); int limit = 50; - //live is X - //rehearsal is Y - plotter.plotTwoVectors(GroundTruth[0], GroundTruth[1], xPlotMin, xPlotMax, yPlotMin, yPlotMax); + //live is X + //rehearsal is Y + plotter.plotTwoVectors(GroundTruth[0], GroundTruth[1], xPlotMin, xPlotMax, yPlotMin, yPlotMax, true); + + //x axis is the live time ofSetColor(0,0,200); - plotter.plotTwoVectors(beatReader.alignmentTimes[1], beatReader.alignmentTimes[0], xPlotMin, xPlotMax, yPlotMin, yPlotMax); - + plotter.plotTwoVectors(beatReader.alignmentTimes[0], beatReader.alignmentTimes[1], xPlotMin, xPlotMax, yPlotMin, yPlotMax, false); + ofSetColor(200,0,0); - plotter.plotTwoVectors(beatReader.alignmentTimes[2], beatReader.alignmentTimes[0], xPlotMin, xPlotMax, yPlotMin, yPlotMax); + plotter.plotTwoVectors(beatReader.alignmentTimes[0], beatReader.alignmentTimes[2], xPlotMin, xPlotMax, yPlotMin, yPlotMax, false); + + ofSetColor(0,200,0); + plotter.plotTwoVectors(matchNotations.matchLiveTimes, matchNotations.matchRehearsalTimes, xPlotMin, xPlotMax, yPlotMin, yPlotMax, false); + } @@ -58,11 +105,13 @@ if (key == OF_KEY_RIGHT){ xPlotMax += 20; xPlotMin += 20; + getYvalues(); } - if (key == OF_KEY_RIGHT){ + if (key == OF_KEY_LEFT){ xPlotMin -= 20; xPlotMax -= 20; + getYvalues(); } if (key == OF_KEY_UP){ @@ -74,6 +123,42 @@ xPlotMax = -1*xPlotMin + 2*xPlotMax ; yPlotMax = -1*xPlotMin + 2*yPlotMax; } + + if (key == 's'){ + screenToDraw++; + + if (screenToDraw == NUMBER_OF_SCREENS) + screenToDraw = 0; + + } + +} + +void testApp::getYvalues(){ +//we have xmin and max +// need the y equivalent + int index = 0; + while (index < beatReader.alignmentTimes[0].size() && beatReader.alignmentTimes[0][index] < xPlotMin){ + index++; + //printf("beat[%i]: %f\n", index, beatReader.alignmentTimes[0][index]); + } + + //printf("found index %i, size %i, at val %.3f\n", index, (int)beatReader.alignmentTimes[0].size(), beatReader.alignmentTimes[0][index]); + + yPlotMin = beatReader.alignmentTimes[1][index]; + + while (index < beatReader.alignmentTimes[0].size() && beatReader.alignmentTimes[0][index] < xPlotMax) + index++; + + yPlotMax = beatReader.alignmentTimes[1][index]; + + + printPlotValues(); +} + +void testApp::printPlotValues(){ + printf("xmin %.0f, mxax %.0f\n", xPlotMin, xPlotMax); + printf("ymin %.0f, ymax %.0f\n", yPlotMin, yPlotMax); } //--------------------------------------------------------------
--- a/annotationCalculatorSrc/testApp.h Fri May 04 16:00:33 2012 +0100 +++ b/annotationCalculatorSrc/testApp.h Tue May 08 21:53:11 2012 +0100 @@ -3,7 +3,10 @@ #include "ofMain.h" #include "BeatAnnotationReader.h" #include "PlotTools.h" +#include "MatchMultitrackAnnotationReader.h" +#include "Histogram.h" +#define NUMBER_OF_SCREENS 3 class testApp : public ofBaseApp{ public: @@ -27,9 +30,21 @@ BeatAnnotationReader beatReader; + void drawAlignmentVectors(); + PlotTools plotter; double xPlotMin, xPlotMax, yPlotMin, yPlotMax; + void getYvalues(); + void printPlotValues(); + std::string matchPath; + MatchMultitrackAnnotationReader matchNotations; + Histogram multiHistogram; + Histogram matchHistogram; + + int screenToDraw; + int histogramWidth, histogramBinNumber; + };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dev notes.txt Tue May 08 21:53:11 2012 +0100 @@ -0,0 +1,3 @@ +TrackType determines which type of chromaOnset + +class ChromaOnset - method processFrame useful for the chromatogram creation
--- a/src/AccompanimentSynchroniser.cpp Fri May 04 16:00:33 2012 +0100 +++ b/src/AccompanimentSynchroniser.cpp Tue May 08 21:53:11 2012 +0100 @@ -9,6 +9,9 @@ #include "AccompanimentSynchroniser.h" +//recorded position millis is the current alignment position, sent from updateAlignment in event matcher +//time sent is the live time since start of play + AccompanimentSynchroniser::AccompanimentSynchroniser(){ sender.setup(HOST, SENDER_PORT); counter = 0;
--- a/src/AudioEventMatcher.cpp Fri May 04 16:00:33 2012 +0100 +++ b/src/AudioEventMatcher.cpp Tue May 08 21:53:11 2012 +0100 @@ -214,7 +214,7 @@ //THIS DEALS WITH WHERE WE ARE NOW! ON THE SCREEN //DIFFERENT TO WHEN EVENTS COME IN AS THEY ARE TIMESTAMPED - SO EG A PITCH EVENT MAY ARRIVE 16 CHROMA FRAMES LATER - BIG DIFFERENCE - int newTime = ofGetElapsedTimeMillis() - startTime; + int newTime = getTimeNow(); // double tmp = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate);; // double timetmp = (newTime - lastAlignmentTime); // double speedtmp = bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); @@ -234,6 +234,11 @@ // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition); } +int AudioEventMatcher::getTimeNow(){ + return ofGetElapsedTimeMillis() - startTime; +} + + void AudioEventMatcher::draw(){ //MAIN DRAW FUNCTION FOR ALL @@ -261,6 +266,8 @@ drawRecordedTempo(); drawPlayingTempo(); + drawAlignmentTimes(); + } @@ -392,7 +399,7 @@ ofDrawBitmapString(tmpStr, 20,140); tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate); ofDrawBitmapString(tmpStr, 20, 180); - ofDrawBitmapString("screenwidth "+ofToString(screenWidthMillis), 20, 800); + //ofDrawBitmapString("screenwidth "+ofToString(screenWidthMillis), 20, 800); ofSetColor(255); tmpStr = "pitch "+ofToString(recentPitch, 2); @@ -411,6 +418,16 @@ } + +void AudioEventMatcher::drawAlignmentTimes(){ + ofSetColor(255); + std::string dataString = "Live time "+ofToString(synchroniser.recordedPositionTimeSent); + dataString += ", Reh time "+ofToString(synchroniser.recordedPositionMillis); + ofDrawBitmapString(dataString, 10, ofGetHeight() - 20); + +} + + void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ if (pitchIn > 0){ liveInput.addPitchEvent(pitchIn, timeIn); @@ -480,7 +497,7 @@ //double quantity = 1;// double quantity = 1*onsetLikelihoodToNoise;//BETTER CHANGE THIS BACK TOO..see below//likelihoodToNoiseRatio / numberOfMatches; int numberOfMatchesFound = 0; - + double nearestOnsetDistance = 1000; double startMatchingTime = bayesianStruct.likelihood.offset; double endMatchingTime = bayesianStruct.likelihood.offset + matchWindowWidth; double millisTime = -1*INFINITY;//or 0 is fine @@ -496,7 +513,8 @@ bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, onsetLikelihoodWidth, quantity); numberOfMatchesFound++; // printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset); - + if (fabs(currentAlignmentPosition - millisTime) < nearestOnsetDistance) + nearestOnsetDistance = currentAlignmentPosition - millisTime; }//end if within limits (changed so it now is 4 sure) } } @@ -517,7 +535,9 @@ temporal.updateTempo(channel, timeIn); } + int timeNow = getTimeNow(); + printf("Nearest onset is %.1f time is %i and alignemnt %i time now %i\n", nearestOnsetDistance, (int) timeIn, (int)currentAlignmentPosition, timeNow); }
--- a/src/AudioEventMatcher.h Fri May 04 16:00:33 2012 +0100 +++ b/src/AudioEventMatcher.h Tue May 08 21:53:11 2012 +0100 @@ -41,9 +41,11 @@ void drawPositionWindow(); void drawTrackLikelihoods(); void drawInfo(); + void drawAlignmentTimes(); void setWindowDimensions(); int getScreenWidthIndexOfEventTime(const double& time); + int getTimeNow(); void newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn); void newKickEvent(const double& timeIn);
--- a/src/testApp.cpp Fri May 04 16:00:33 2012 +0100 +++ b/src/testApp.cpp Tue May 08 21:53:11 2012 +0100 @@ -103,8 +103,8 @@ if ( m.getAddress() == "/start" ){ printf("start!\n"); printf("STRART TIME IN %i\n", ofGetElapsedTimeMillis()); + outputWriter.openFile(); eventMatcher.startPlaying(); - outputWriter.openFile(); printf("TIME OUT %i\n", ofGetElapsedTimeMillis()); }