Mercurial > hg > multitrack-audio-matcher
view annotationCalculatorSrc/BeatAnnotationReader.cpp @ 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 |
line wrap: on
line source
/* * BeatAnnotationReader.cpp * annotationResultCalculator * * Created by Andrew on 03/05/2012. * Copyright 2012 QMUL. All rights reserved. * */ #include "BeatAnnotationReader.h" void BeatAnnotationReader::readInBeatsFile(std::string& pathName){ // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv" beatTimes.clear(); // printf("MATCH : READ FILE %s\n", pathName.c_str()); ifstream file ( pathName.c_str()); string value, tmpLine; stringstream iss; int count = 0; while ( file.good() ) { getline(file, tmpLine); iss << tmpLine; int lineCount = 0; // 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 part = value.substr(start, string::npos); //printf("%s\n", firstpart.c_str()); if (lineCount == 0){ //printf("First part of line found '%s'\n", part.c_str()); double newBeatTime = atof(part.c_str()); beatTimes.push_back(newBeatTime); } lineCount++; /* 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.audioTime = atof(part.c_str()); n.midiTime = atof(secondpart.c_str()); matchData.push_back(n); */ }//end while reading line iss.clear(); }//end while printBeatTimes(); // printf("There are %i MATCH annotations\n", (int)matchData.size()); } void BeatAnnotationReader::printBeatTimes(){ for (int i = 0;i < beatTimes.size();i++){ printf("Beat[%i] = %f\n", i, beatTimes[i]); } } void BeatAnnotationReader::readInMultiAlignmentFile(std::string pathName){ alignmentTimes.clear(); DoubleVector liveFileTimes; DoubleVector multialignTimes; DoubleVector playedAlignTimes; ifstream file ( pathName.c_str()); string value, tmpLine; stringstream iss; int count = 0; while ( file.good() ) { getline(file, tmpLine); iss << tmpLine; int lineCount = 0; // 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 part = value.substr(start, string::npos); //printf("%s\n", firstpart.c_str()); if (lineCount == 0){ printf("First part of align found '%s'\n", part.c_str()); double newBeatTime = atof(part.c_str()); liveFileTimes.push_back(newBeatTime); } if (lineCount == 1){ printf("Second part of align found '%s'\n", part.c_str()); double newAlignTime = atof(part.c_str()); multialignTimes.push_back(newAlignTime); } if (lineCount == 2){ printf("Third part of align found '%s'\n", part.c_str()); double newAlignTime = atof(part.c_str()); playedAlignTimes.push_back(newAlignTime); } lineCount++; }//end while reading line iss.clear(); }//end while alignmentTimes.push_back(liveFileTimes); alignmentTimes.push_back(multialignTimes); 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); } }