Mercurial > hg > midi-score-follower
changeset 50:158f5f38e9d3
outputting exact difference for annotations, comparison with match annotations is now working over all rwc files
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Thu, 29 Mar 2012 13:41:59 +0100 |
parents | 3ce6dadd8167 |
children | ef30f465a904 |
files | jnmr/Annotations.cpp jnmr/BayesianArrayStructure.cpp jnmr/BayesianArrayStructure.h jnmr/midiEventHolder.cpp jnmr/midiEventHolder.h jnmr/testApp.cpp matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp matchAnnotationSrc/matchAnnotations.cpp matchAnnotationSrc/testApp.cpp matchAnnotationSrc/testApp.h |
diffstat | 10 files changed, 314 insertions(+), 115 deletions(-) [+] |
line wrap: on
line diff
--- a/jnmr/Annotations.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/Annotations.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -18,7 +18,7 @@ // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv" rwcAnnotations.clear(); - printf("ANNOTATIONS : READ FILE %s\n", pathName.c_str()); +// printf("ANNOTATIONS : READ FILE %s\n", pathName.c_str()); ifstream file ( pathName.c_str()); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/ string value, tmpLine; stringstream iss;
--- a/jnmr/BayesianArrayStructure.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/BayesianArrayStructure.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -14,7 +14,9 @@ BayesianArrayStructure::BayesianArrayStructure(){ printf("Bayesian structure: DeFault constructor called\n"); - usingIntegratedTempoEstimate = true;// use max index + usingIntegratedTempoEstimate = false;// use max index + + useConstantTempoDistribution = false; relativeSpeedLikelihoodStdDev = 5.0; @@ -173,6 +175,7 @@ posterior.getMaximum(); bestEstimate = posterior.getRealTermsAsIndex(0); + printf("bayes reset arrays - best estimate time %f\n", lastBestEstimateUpdateTime); setSpeedPrior(speedPriorValue); @@ -459,6 +462,13 @@ relativeSpeedPosterior.updateLimitedIntegratedEstimate(); speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate); + + if (useConstantTempoDistribution){ + //tmp try constant tempo + relativeSpeedPosterior.zero(); + relativeSpeedPosterior.addConstant(1); + relativeSpeedPosterior.renormalise(); + } }
--- a/jnmr/BayesianArrayStructure.h Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/BayesianArrayStructure.h Thu Mar 29 13:41:59 2012 +0100 @@ -95,6 +95,6 @@ bool* realTimeMode; bool usingIntegratedTempoEstimate; double relativeSpeedLikelihoodStdDev; - + bool useConstantTempoDistribution; }; #endif
--- a/jnmr/midiEventHolder.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/midiEventHolder.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -35,7 +35,7 @@ confidenceWeightingUsed = true; newOptimalMethod = true; - matchWindowWidth = 16000;//window size for matching in ms + matchWindowWidth = 20000;//window size for matching in ms interNoteRange = 1600;//preferred duration //so max here is really four @@ -44,7 +44,7 @@ likelihoodToNoiseRatio = 0.20;//was 0.02 on 18/11/11, changing to give more weight to observations //was 0.08 on 11/12/11 but need more for tempo varn in rwc database - bayesStruct.speedLikelihoodNoise = 0.1;//was 0.05 + bayesStruct.speedLikelihoodNoise = 0.2;//changed from 0.1, was 0.05 bayesStruct.speedDecayWidth = 40; bayesStruct.speedDecayAmount = 10; @@ -131,7 +131,7 @@ interNoteIntervals.clear(); - smoothIndex = 0; + outputIndex = 0; smoothPlayPosition = 0.0; causalPlayPosition = 0; lastCausalUpdateTime = getTimeNow(0); @@ -157,6 +157,21 @@ //period = 500.0; } +void midiEventHolder::testSpeedPriorSetting(){ + if (speedPriorValue > 2){ + bayesStruct.resetSpeedSize(speedPriorValue * 200); + bayesStruct.setRelativeSpeedScalar(0.01); + bayesStruct.relativeSpeedPrior.getMaximum(); + printf("SPEED SIZE EXCEEDS MAXIMUM!!! RESETTING TO SIXE %i\n", (int)(speedPriorValue * 200)); + } + else{ + bayesStruct.resetSpeedSize(200); + bayesStruct.setRelativeSpeedScalar(0.01); + bayesStruct.relativeSpeedPrior.getMaximum(); + } + +} + void midiEventHolder::setMatchedNotesBackToFalse(){ for (int i = 0;i < noteOnMatches.size();i++) noteOnMatches[i] = false; @@ -309,14 +324,13 @@ void midiEventHolder::updateTempo(){ //having found matches we have matches for new note and matches for previous notes - if (newOptimalMethod) + if (newOptimalMethod)//now true findOptimumTempoPairsToCurrentBestMatch(); else if (!confidenceWeightingUsed) findLocalTempoPairs(); else findLocalTempoPairsWeightedForConfidence(); - //bayesStruct.addGaussianNoiseToSpeedPosterior(10); } @@ -376,6 +390,7 @@ if (recordedEventTimes.size() > 0){ //get to the right range of events to check in + //OPTIMIZE! while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < startTime) startIndex++; @@ -396,7 +411,7 @@ double eventConfidence = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[startIndex]); if (eventConfidence > minimumConfidence){ minimumConfidence = eventConfidence; - bestMatchIndex = startIndex; + bestMatchIndex = startIndex;//could change this to minimumMatchError below } d.push_back(eventConfidence); @@ -408,6 +423,7 @@ //record the error between expected and observed times tmpError = abs(recordedEventTimes[startIndex] - bayesStruct.bestEstimate); minimumMatchError = tmpError;//recordedEventTimes[startIndex] - bayesStruct.bestEstimate; + // bestMatchIndex = startIndex; } } @@ -794,15 +810,22 @@ //did just update smooth to current if it was less if (smoothPlayPosition < bayesStruct.bestEstimate){ - updateSmoothPositionTo(bayesStruct.bestEstimate); - //smoothPlayPosition = bayesStruct.bestEstimate; + // updateOutputPositionTo(bayesStruct.bestEstimate); + smoothPlayPosition = bayesStruct.bestEstimate; } + updateOutputPositionTo(causalPlayPosition); //need it outputting before the update + + updateCausalPlayPosition(getTimeNow(bayesStruct.lastBestEstimateUpdateTime)); + - updateCausalPlayPosition(getTimeNow(bayesStruct.lastBestEstimateUpdateTime)); + //can choose to output either the smooth position (i.e. forwards) + //or causal play position which aims toward our current smooth position in near future -/* + + + /* //now we try updating it to a causal path that tries to match into the future if (smoothPlayPosition < causalPlayPosition){ updateSmoothPositionTo(causalPlayPosition); @@ -822,101 +845,134 @@ } -void midiEventHolder::updateSmoothPositionTo(const double& newPosition){ +void midiEventHolder::updateOutputPositionTo(const double& newPosition){ //smooth play position was where we last outputted notes from. //checking index is there to make sense. - while (smoothIndex > 0 && recordedEventTimes[smoothIndex] > smoothPlayPosition){ - smoothIndex--; - //printf("going backewaers on smooth, "); +// double checkPosition = smoothPlayPosition; + double checkPosition = lastUpdatePosition; + + + while (outputIndex > 0 && recordedEventTimes[outputIndex] > checkPosition){ + outputIndex--; +// printf("going backewards, smooth time %f, ", recordedEventTimes[outputIndex]); } - while (smoothIndex < recordedEventTimes.size()-1 && recordedEventTimes[smoothIndex] < smoothPlayPosition){ - smoothIndex++; - //printf("outputting smooth\n "); + while (outputIndex < recordedEventTimes.size()-1 && recordedEventTimes[outputIndex] < checkPosition){ + outputIndex++; +// printf("outputting smooth forwards time %f\n ", recordedEventTimes[outputIndex], checkPosition); } +// printf("last output position %f, new position %f\n", checkPosition, newPosition); +// printf("causal pos %.0f, smooth pos %.0f, best est %.0f\n", causalPlayPosition, smoothPlayPosition, bayesStruct.bestEstimate); + + outputPosition = recordedEventTimes[outputIndex]; double playingTime = ofGetElapsedTimeMillis(); playingTime -= startPlayingTime; //now at the last one - float smoothLocation = beatPositions[smoothIndex]; - int currentNote = recordedNoteOnMatrix[smoothIndex][1]; + float smoothLocation = beatPositions[outputIndex]; + int currentNote = recordedNoteOnMatrix[outputIndex][1]; - while (smoothIndex < recordedEventTimes.size() && recordedEventTimes[smoothIndex] < newPosition){ + while (outputIndex < recordedEventTimes.size() && recordedEventTimes[outputIndex] < newPosition){ float annotationTime = 0; float annotationLocation = 0; int annotationTick = 0; int annotationNote = 0; float difference = 10000;//very big - float currentLocationDifference = 1.0; + //float currentLocationDifference = 1.0; + + double amountSinceLastUpdate = 0.0;//between 0 and 1, the exact position of this event since last update + if (newPosition > lastUpdatePosition){ + amountSinceLastUpdate = (recordedEventTimes[outputIndex] - lastUpdatePosition)/(newPosition - lastUpdatePosition); + } + float range = 1.0; - if (smoothIndex < myNotation.rwcAnnotations.size()){ + if (outputIndex < myNotation.rwcAnnotations.size()){ //add in test here to find closest matching note - annotationTime = myNotation.rwcAnnotations[smoothIndex].eventTime; - annotationNote = myNotation.rwcAnnotations[smoothIndex].midiNote; - annotationLocation = myNotation.rwcAnnotations[smoothIndex].beatLocation; + annotationTime = myNotation.rwcAnnotations[outputIndex].eventTime; + annotationNote = myNotation.rwcAnnotations[outputIndex].midiNote; + annotationLocation = myNotation.rwcAnnotations[outputIndex].beatLocation; annotationTick = round(annotationLocation*480.0); }else{ printf("No annotaion size %i\n", (int)myNotation.rwcAnnotations.size()); } + double exactPlayingTime = amountSinceLastUpdate*playingTime + ((1 - amountSinceLastUpdate)*lastUpdatePlayingTime); difference = playingTime - (annotationTime*1000.0); - - if ((*fileOutput).is_open()){ - (*fileOutput) << fixed << beatPositions[smoothIndex] <<",\t" << recordedNoteOnMatrix[smoothIndex][1] << ",\t"; + double exactDifference = exactPlayingTime - (annotationTime*1000.0); + /* + //NO LONGER NEEDED ALLO + if ((*fileOutput).is_open()){ + (*fileOutput) << fixed << beatPositions[outputIndex] <<",\t" << recordedNoteOnMatrix[outputIndex][1] << ",\t"; (*fileOutput) << playingTime ; - if ( recordedNoteOnMatrix[smoothIndex][1] == annotationNote){ + if ( recordedNoteOnMatrix[outputIndex][1] == annotationNote){ (*fileOutput) << " corresponds to " << annotationTime; } (*fileOutput) << " \n"; } - - printf("annotations: rec tick time %i vs %i midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n", - recordedNoteOnMatrix[smoothIndex][0], annotationTick, recordedNoteOnMatrix[smoothIndex][1], - beatPositions[smoothIndex], playingTime, - annotationNote, annotationLocation, annotationTime, difference); + */ -// assert(annotationNote == recordedNoteOnMatrix[smoothIndex][1]); - assert(annotationTick == recordedNoteOnMatrix[smoothIndex][0]); + //useful printing stuff +// printf("playing time %.1f, annotation time %.1f, diff %.1f\n", playingTime, (annotationTime*1000.0), difference); + +// printf("last posn %.1f, amount since %.2f \n" lastUpdatePosition, amountSinceLastUpdate); + +// printf("annotations:Diff %f rec tick time %i vs %i midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n", +// difference, recordedNoteOnMatrix[outputIndex][0], annotationTick, recordedNoteOnMatrix[outputIndex][1], +// beatPositions[outputIndex], playingTime, +// annotationNote, annotationLocation, annotationTime, difference); + + // we use exact difference as it more accurately predicts where we scheduled the note +// printf("diff %.1f, exact diff %.1f\n", difference, exactDifference); + + + //assert(annotationNote == recordedNoteOnMatrix[outputIndex][1]); + assert(annotationTick == recordedNoteOnMatrix[outputIndex][0]); smoothDifference = difference; if ((*differenceOutput).is_open()){ - (*differenceOutput) << beatPositions[smoothIndex] << "," << difference << "," << playingTime << "," << (annotationTime*1000.0) << "\n"; + (*differenceOutput) << beatPositions[outputIndex] << "," << exactDifference << "," << playingTime << "," << (annotationTime*1000.0) << annotationNote << difference << "\n"; // printf("midi %i beat pos %f playing time now at %f :: annotaion %i loc % f time %f diff \t%f ms\n", - // recordedNoteOnMatrix[smoothIndex][1], - // beatPositions[smoothIndex], playingTime, + // recordedNoteOnMatrix[outputIndex][1], + // beatPositions[outputIndex], playingTime, // annotationNote, annotationLocation, annotationTime, difference); }else{ printf("file not open\n"); } - smoothIndex++; + outputIndex++; } - - smoothPlayPosition = newPosition; - + lastUpdatePosition = newPosition; + lastUpdatePlayingTime = playingTime; } void midiEventHolder::updateCausalPlayPosition(const double& timeNow){ //projected position + //first update the speed + updateCausalSpeed(); + + causalPlayPosition += causalSpeed * (timeNow - lastCausalUpdateTime); + lastCausalUpdateTime = timeNow; + +} + +void midiEventHolder::updateCausalSpeed(){ double difference = bayesStruct.bestEstimate - causalPlayPosition; causalSpeed = bayesStruct.speedEstimate; causalSpeed += (difference/timeProjectionToMeet); if (causalSpeed < 0) causalSpeed = 0; - - causalPlayPosition += causalSpeed * (timeNow - lastCausalUpdateTime); - lastCausalUpdateTime = timeNow; - + } + /* void midiEventHolder::updatePeriodValue(const double& millis){ @@ -981,7 +1037,7 @@ if (checkIfMatchedNote(tmpIndex)) ofSetColor(100,100,100);//0,0,255); else if(noteOnMatches[tmpIndex]){ - ofSetColor(255,0,255);//dark grey + ofSetColor(255,0,255);//pink } else{ ofSetColor(255,255,255);//255,255,255); @@ -1011,10 +1067,14 @@ ofSetColor(250,250,20);//250,100,0); ofLine(xLocation, 0, xLocation, (*screenHeight)); + +/* + //cyan blue - smooth position xLocation = getLocationFromMillis(smoothPlayPosition);//bayesStruct.tmpBestEstimate - ofSetColor(0,250,0);//250,150, 250,100,0); - // ofLine(xLocation, 0, xLocation, (*screenHeight)); - + ofSetColor(0,250,250);//250,150, 250,100,0); + ofLine(xLocation, 0, xLocation, (*screenHeight)); +*/ + //bright green is the causal play position xLocation = getLocationFromMillis(causalPlayPosition);//bayesStruct.tmpBestEstimate ofSetColor(0,250,0);//250,150, 250,100,0); ofLine(xLocation, 0, xLocation, (*screenHeight)); @@ -1049,9 +1109,16 @@ //ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); ofSetColor(255,255,255); ofDrawBitmapString(timeString, 20, 60); - ofDrawBitmapString("diff "+ofToString(smoothDifference), 20, 140); + string diffString = "diff "+ofToString(smoothDifference); + diffString += "\ncausal posn: "+ofToString(causalPlayPosition, 0); + diffString += "\nsmooth posn: "+ofToString(smoothPlayPosition, 0); + diffString += "\noutput posn: "+ofToString(outputPosition, 0); + diffString += "\nbest est: "+ofToString(bayesStruct.bestEstimate, 0); + diffString += "\nlast best est: "+ofToString(bayesStruct.lastBestEstimateUpdateTime, 0); -//last played piutch + ofDrawBitmapString(diffString, 20, 140); + + //last played pitch ofSetColor(0,200,0,50); int yLocation = (*screenHeight) - ((lastPlayedPitch - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum)); ofRect(0,yLocation, 100, noteHeight); @@ -1448,7 +1515,7 @@ /* JUNK SMOOTH StuffHex /* - int testIndex = smoothIndex; + int testIndex = outputIndex; while (testIndex >= 0 && abs(smoothLocation - myNotation.rwcAnnotations[testIndex].beatLocation) < range){ if (myNotation.rwcAnnotations[testIndex].midiNote == currentNote){ @@ -1463,7 +1530,7 @@ testIndex--; } - testIndex = smoothIndex; + testIndex = outputIndex; while (testIndex >= 0 && testIndex < myNotation.rwcAnnotations.size() && abs(smoothLocation - myNotation.rwcAnnotations[testIndex].beatLocation) < range){ if (myNotation.rwcAnnotations[testIndex].midiNote == currentNote){
--- a/jnmr/midiEventHolder.h Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/midiEventHolder.h Thu Mar 29 13:41:59 2012 +0100 @@ -180,11 +180,12 @@ double causalPlayPosition; void updateCausalPlayPosition(const double& timeNow); + void updateCausalSpeed(); double lastCausalUpdateTime ; double causalSpeed; - void updateSmoothPositionTo(const double& newPosition); - int smoothIndex; + void updateOutputPositionTo(const double& newPosition); + int outputIndex; DoubleVector beatPositions; ofstream *fileOutput; @@ -193,5 +194,9 @@ double timeProjectionToMeet;///ms in future they will intersect double smoothDifference; + double lastUpdatePosition, lastUpdatePlayingTime; + double outputPosition;//debug variable + + void testSpeedPriorSetting(); }; #endif \ No newline at end of file
--- a/jnmr/testApp.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/jnmr/testApp.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -14,13 +14,13 @@ root = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/Classical_RWC_Groundtruth/RM-C0"; outputFileRoot = "../../../data/FilesOut/rwcOutputData_RM-C0"; annotationRoot = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/ANNOTATION/RM-C0"; - myfile.open("../../../data/FilesOut/exampletest2.txt"); + //myfile.open("../../../data/FilesOut/exampletest2.txt"); //diffFile.open("../../../data/FilesOut/diffTest.txt"); - midiEvents.fileOutput = &myfile; +// midiEvents.fileOutput = &myfile; @@ -220,6 +220,7 @@ float playedDuration = m.getArgAsFloat(0); double recordedDuration = midiEvents.recordedEventTimes[midiEvents.recordedEventTimes.size()-1]; midiEvents.speedPriorValue = recordedDuration/playedDuration; + midiEvents.testSpeedPriorSetting(); printf("played duration %f, recorded %f\n", playedDuration, recordedDuration); printf("speed prior set to %f\n", midiEvents.bayesStruct.speedPriorValue); @@ -595,7 +596,7 @@ sendNoteToMuseScore(); diffFile.close(); - myfile.close(); + //myfile.close(); }
--- a/matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/matchAnnotationSrc/jnmrMidiPlayerAnnotations.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -15,7 +15,7 @@ jnmrMidiPlayerData.clear(); differences.clear(); - printf("jnmrMidiPlayer : READ FILE %s\n", pathName.c_str()); +// printf("jnmrMidiPlayer : READ FILE %s\n", pathName.c_str()); ifstream file ( pathName.c_str()); string value, tmpLine; stringstream iss; @@ -93,7 +93,7 @@ }//end while //printAnnotations(); - printf("There are %i JNMR annotations\n", (int)jnmrMidiPlayerData.size()); +// printf("There are %i JNMR annotations\n", (int)jnmrMidiPlayerData.size()); }
--- a/matchAnnotationSrc/matchAnnotations.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/matchAnnotationSrc/matchAnnotations.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -15,7 +15,7 @@ // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv" matchData.clear(); - printf("MATCH : READ FILE %s\n", pathName.c_str()); +// printf("MATCH : READ FILE %s\n", pathName.c_str()); ifstream file ( pathName.c_str()); string value, tmpLine; stringstream iss; @@ -48,7 +48,7 @@ }//end while // printAnnotations(); - printf("There are %i MATCH annotations\n", (int)matchData.size()); +// printf("There are %i MATCH annotations\n", (int)matchData.size()); }
--- a/matchAnnotationSrc/testApp.cpp Fri Mar 23 10:53:57 2012 +0000 +++ b/matchAnnotationSrc/testApp.cpp Thu Mar 29 13:41:59 2012 +0100 @@ -4,38 +4,61 @@ void testApp::setup(){ //fixed stuff annotationRoot = "/Users/andrew/Documents/work/Alignment/MuseScore/RWC/ANNOTATION/RM-C0"; - jnmrPlayerRoot = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/savedOutputs/rwcOutputData_RM-C0"; + jnmrPlayerRoot = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/completeTestsTempoMAPestimate/rwcOutputData_RM-C0"; createRWCfilenameStrings(); + fileNumberToTest = 0; + loadAnnotation(fileNumberToTest); + getResults(fileNumberToTest); +} + +void testApp::getResults(const int& fileID){ - std::string matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/matchOutput/RWCmatch_RM-C0"; - std::string matchEnd = "_ob.out"; std::string txtEnd = ".txt"; //naming convention //match output must also follow the RWC ID //01, 02, 03 etc + std::string matchEnd = "_ob.out"; + matchPath = makeMatchFilename(fileID, matchEnd);//makeRWCfilename(matchRoot, fileID, matchEnd); + printf("MATCH PATH OB: %s\n", matchPath.c_str()); + matchNotations.readInMatchFile(matchPath); + TimingResult matchObResult; + calculateMatchErrors(matchObResult); + matchOB_results.push_back(matchObResult); + matchEnd = "_of.out"; + matchPath = makeMatchFilename(fileID, matchEnd);//makeRWCfilename(matchRoot, fileID, matchEnd); + printf("MATCH PATH OF: %s\n", matchPath.c_str()); + matchNotations.readInMatchFile(matchPath); + TimingResult matchOfResult; + calculateMatchForwardErrors(matchOfResult); + matchOF_results.push_back(matchOfResult); - int fileID = 2; - - matchPath = makeRWCfilename(matchRoot, fileID, matchEnd); - printf("MATCH PATH\n", matchPath.c_str()); - matchNotations.readInMatchFile(matchPath); - - - loadAnnotation(fileID); - - printf("MATCH\n"); - calculateMatchErrors(); jnmrPlayerPath = makeRWCfilename(jnmrPlayerRoot, fileID, txtEnd);//+ "rwcOutputData_RM-C003.txt"; jnmrPlayerAnnotations.readInjnmrMidiPlayerFile(jnmrPlayerPath); printf("JNMR DIFFERENCES\n"); - sortDifferenceVector(jnmrPlayerAnnotations.differences); + TimingResult jnmrResult; + sortDifferenceVector(jnmrPlayerAnnotations.differences, jnmrResult); + JNMR_MidiMatcher_results.push_back(jnmrResult); + + printf("\n"); +} + + +std::string testApp::makeMatchFilename( const int& fileID, std::string matchEnd){ + std::string matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/completeMatchOut/RWCmatch_RM-C"; + + string rootToUse = matchRoot; + if (fileID > 8){ + rootToUse += "0"; + } + string matchName = makeRWCfilename(rootToUse, fileID, matchEnd); + return matchName; } @@ -103,7 +126,7 @@ } -void testApp::calculateMatchErrors(){ +void testApp::calculateMatchErrors(TimingResult& t){ int matchIndex = 0; vector<float> matchDiffs; @@ -129,38 +152,44 @@ matchDiffs.push_back(fabs(matchDifference)); } - sortDifferenceVector(matchDiffs); - /* -//GETS MEAN AND MEDIAN - int count = 0; - float total = 0; - - for (int i = 0;i < matchDiffs.size();i++){ - // printf("M[%i] : %f\n", i, matchDiffs[i]); - - count++; - total += fabs(matchDiffs[i]); - - } - total /= count; - - std::sort(matchDiffs.begin(), matchDiffs.end()); - -// printf("SORTED TWO HUNDRED\n"); - -// for (int i = 0;i < matchDiffs.size() ;i++){ -// printf("M[%i] : %f\n", i, matchDiffs[i]); -// } - - printf("MATCH median %f, mean is %f\n", matchDiffs[(int)(matchDiffs.size()/2)], total); - */ - - + sortDifferenceVector(matchDiffs, t); } -void testApp::sortDifferenceVector(vector<float> diffVec){ +void testApp::calculateMatchForwardErrors(TimingResult& t){ + int matchIndex = 0; + + vector<float> matchDiffs; + + for (int i = 0;i < rwcAnnotations.rwcAnnotations.size();i++){ + // printf("rwc time %f midi time %f\n", rwcAnnotations.rwcAnnotations[i].eventTime, rwcAnnotations.rwcAnnotations[i].midiTime); + + while (matchIndex < matchNotations.matchData.size() && matchNotations.matchData[matchIndex].midiTime > rwcAnnotations.rwcAnnotations[i].midiTime) + matchIndex++; + + while (matchNotations.matchData[matchIndex].midiTime < rwcAnnotations.rwcAnnotations[i].midiTime) + matchIndex--; + + // float matchFraction = (rwcAnnotations.rwcAnnotations[i].midiTime - matchNotations.matchData[matchIndex].midiTime)/(matchNotations.matchData[matchIndex+1].midiTime - matchNotations.matchData[matchIndex].midiTime); + // matchFraction *= (matchNotations.matchData[matchIndex+1].audioTime - matchNotations.matchData[matchIndex].audioTime); + float matchTime = matchNotations.matchData[matchIndex].audioTime;// +matchFraction ; + + // printf("matchTime %f gives event time %f from flat event time %f\n", matchNotations.matchData[matchIndex].midiTime, matchTime, matchNotations.matchData[matchIndex].audioTime); + + float matchDifference = 1000.0*(matchTime - rwcAnnotations.rwcAnnotations[i].eventTime); + // printf("Match diff %f\n", matchDifference); + + matchDiffs.push_back(fabs(matchDifference)); + } + + sortDifferenceVector(matchDiffs, t); + +} + + + +void testApp::sortDifferenceVector(vector<float> diffVec, TimingResult& t){ //GETS MEAN AND MEDIAN int count = 0; @@ -172,6 +201,8 @@ count++; total += fabs(diffVec[i]); diffVec[i] = fabs(diffVec[i]);//replace with +ve value + + addToPercentiles(diffVec[i], t); } total /= count; @@ -183,12 +214,47 @@ printf("Sort[%i] : %f\n", i, diffVec[i]); } */ - printf("Count %i Median %f, mean is %f\n", count, diffVec[(int)(diffVec.size()/2)], total); + printf("Count %i Median %3.1f, mean is %3.1f\n", count, diffVec[(int)(diffVec.size()/2)], total); + t.median = diffVec[(int)(diffVec.size()/2)]; + t.mean = total; + t.count = count; + for (int i = 0;i < 7;i++){ + t.percentiles[i] = t.percentileCount[i] / count; + printf("Perc[%i] = %2.1f, ", i, (t.percentiles[i]*100.0)); + } + printf("\n"); } +void testApp::addToPercentiles(float value, TimingResult& t){ + + if (value <= 20){ + t.percentileCount[0]++; + } + if (value <= 40){ + t.percentileCount[1]++; + } + if (value <= 60){ + t.percentileCount[2]++; + } + if (value <= 100){ + t.percentileCount[3]++; + } + if (value <= 200){ + t.percentileCount[4]++; + } + if (value <= 500){ + t.percentileCount[5]++; + } + if (value <= 1000){ + t.percentileCount[6]++; + } + + +} + //-------------------------------------------------------------- void testApp::update(){ @@ -202,6 +268,12 @@ //-------------------------------------------------------------- void testApp::keyPressed(int key){ + if (key == ' '){ + fileNumberToTest++; + loadAnnotation(fileNumberToTest); + getResults(fileNumberToTest); + } + } //-------------------------------------------------------------- @@ -242,4 +314,29 @@ //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){ -} \ No newline at end of file +} + +/* + //GETS MEAN AND MEDIAN + int count = 0; + float total = 0; + + for (int i = 0;i < matchDiffs.size();i++){ + // printf("M[%i] : %f\n", i, matchDiffs[i]); + + count++; + total += fabs(matchDiffs[i]); + + } + total /= count; + + std::sort(matchDiffs.begin(), matchDiffs.end()); + + // printf("SORTED TWO HUNDRED\n"); + + // for (int i = 0;i < matchDiffs.size() ;i++){ + // printf("M[%i] : %f\n", i, matchDiffs[i]); + // } + + printf("MATCH median %f, mean is %f\n", matchDiffs[(int)(matchDiffs.size()/2)], total); + */
--- a/matchAnnotationSrc/testApp.h Fri Mar 23 10:53:57 2012 +0000 +++ b/matchAnnotationSrc/testApp.h Thu Mar 29 13:41:59 2012 +0100 @@ -6,6 +6,15 @@ #include "matchAnnotations.h" #include "jnmrMidiPlayerAnnotations.h" +struct TimingResult{ + double median; + double mean; + int count; + double percentileCount[7]; + double percentiles[7]; + int type; +}; + class testApp : public ofBaseApp{ public: @@ -33,13 +42,23 @@ void loadAnnotation(const int& fileID); string matchPath; + std::string makeMatchFilename( const int& fileID, std::string matchEnd); matchAnnotations matchNotations; string jnmrPlayerPath, jnmrPlayerRoot; jnmrMidiPlayerAnnotations jnmrPlayerAnnotations; - void calculateMatchErrors(); - void sortDifferenceVector(vector<float> diffVec); + void calculateMatchErrors(TimingResult& t); + void calculateMatchForwardErrors(TimingResult& t); + void sortDifferenceVector(vector<float> diffVec, TimingResult& t); + void addToPercentiles(float value, TimingResult& t); + + vector<TimingResult> matchOF_results; + vector<TimingResult> matchOB_results; + vector<TimingResult> JNMR_MidiMatcher_results; + + void getResults(const int& fileID); + int fileNumberToTest; };