Mercurial > hg > midi-score-follower
changeset 52:13194a9dca77 tip
Added exporting of image and text data
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Tue, 17 Jul 2012 22:13:10 +0100 |
parents | ef30f465a904 |
children | |
files | jnmr/BayesianArrayStructure.cpp jnmr/BayesianArrayStructure.h jnmr/midiEventHolder.cpp jnmr/midiEventHolder.h jnmr/testApp.cpp matchAnnotationSrc/testApp.cpp |
diffstat | 6 files changed, 204 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/jnmr/BayesianArrayStructure.cpp Sat Mar 31 14:04:49 2012 +0100 +++ b/jnmr/BayesianArrayStructure.cpp Tue Jul 17 22:13:10 2012 +0100 @@ -12,6 +12,9 @@ #include "BayesianArrayStructure.h" +int priorColor = 0xEE00CC;//230,0,170 +int posteriorColor = 0x444444;//000099; + BayesianArrayStructure::BayesianArrayStructure(){ printf("Bayesian structure: DeFault constructor called\n"); usingIntegratedTempoEstimate = false;// use max index @@ -21,7 +24,7 @@ relativeSpeedLikelihoodStdDev = 5.0; prior.createVector(1); - likelihood.createVector(1); + likelihood.createVector(1); posterior.createVector(1); @@ -34,6 +37,10 @@ crossUpdateTimeThreshold = 60; priorWidth = 50; + drawLikelihood = false; + drawPrior = true; + drawPosterior = true; + } BayesianArrayStructure::BayesianArrayStructure(int length){ @@ -566,18 +573,21 @@ // ofDrawBitmapString(relativeString, 100, 180); + if (drawLikelihood){ + ofSetColor(100,100,100);//255, 255, 0); + likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + } - ofSetColor(100,100,100);//255, 255, 0); - likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); - -// ofSetColor(0,0,200); - ofSetColor(230,0,170);//00,200); - prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + if (drawPrior){ + ofSetHexColor(priorColor);//00,200); + prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + } - ofSetColor(0,0,150); -// ofSetColor(200, 0, 0); - posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); - + if (drawPosterior){ + ofSetHexColor(posteriorColor); + // ofSetColor(200, 0, 0); + posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + } // ofSetColor(0, 200, 255); // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
--- a/jnmr/BayesianArrayStructure.h Sat Mar 31 14:04:49 2012 +0100 +++ b/jnmr/BayesianArrayStructure.h Tue Jul 17 22:13:10 2012 +0100 @@ -96,5 +96,9 @@ bool usingIntegratedTempoEstimate; double relativeSpeedLikelihoodStdDev; bool useConstantTempoDistribution; + + bool drawLikelihood; + bool drawPrior; + bool drawPosterior; }; #endif
--- a/jnmr/midiEventHolder.cpp Sat Mar 31 14:04:49 2012 +0100 +++ b/jnmr/midiEventHolder.cpp Tue Jul 17 22:13:10 2012 +0100 @@ -22,6 +22,11 @@ #include <fstream> #include <assert.h> +#pragma mark -initialise + +int matchedColor = 0xAAAAAA; +int bestMatchedColor = 0xFF0000; + midiEventHolder::midiEventHolder(){ timeProjectionToMeet = 600;//ms in future they will intersect bet predicted and causal play position @@ -34,15 +39,16 @@ useTempoPrior = false;//puts sine wave round tempo confidenceWeightingUsed = true; newOptimalMethod = true; + printInfo = false; matchWindowWidth = 20000;//window size for matching in ms interNoteRange = 1600;//preferred duration //so max here is really four - likelihoodWidth = 100;//using 100 is good - likelihoodToNoiseRatio = 0.20;//was 0.02 on 18/11/11, changing to give more weight to observations + likelihoodToNoiseRatio = 0.80;//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 + //0.2 on main tests of bayesStruct.speedLikelihoodNoise = 0.2;//changed from 0.1, was 0.05 bayesStruct.speedDecayWidth = 40; @@ -69,10 +75,6 @@ noteArrayIndex = 0; noteMinimum = 30; noteMaximum = 96; - - - - speedPriorValue = 1.0; @@ -86,12 +88,10 @@ bayesStruct.relativeSpeedPrior.getMaximum(); //bayesStruct.simpleExample(); - speedWindowWidthMillis = 1600;//4000 noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum); - intervalsToCheck.push_back(1); intervalsToCheck.push_back(2); //intervalsToCheck.push_back(3); @@ -100,8 +100,8 @@ intervalsToCheck.push_back(8); intervalsToCheck.push_back(16); - drawPhaseMode = true; + saveImage = false; printf("lookup index %f value %f\n", bayesStruct.prior.getLookupIndex(100, 30., 10.0), bayesStruct.prior.gaussianLookupTable[(int)bayesStruct.prior.getLookupIndex(100, 30., 10.0)]); } @@ -157,6 +157,26 @@ //period = 500.0; } +void midiEventHolder::clearAllEvents(){ + recordedNoteOnMatrix.clear(); + matchesFound.clear(); + noteOnMatches.clear(); + recordedEventTimes.clear(); + measureVector.clear(); + //played events: + playedEventTimes.clear(); + playedNoteOnMatrix.clear(); + matchMatrix.clear(); + bestMatchFound.clear(); + periodValues.clear(); + + beatPositions.clear(); + + recordedTotalNoteCounterByPitch.clear(); + recordedTotalNoteCounterByPitch.assign(127, 0); + totalNoteCounterIndex = 0; +} + void midiEventHolder::testSpeedPriorSetting(){ if (speedPriorValue > 2){ bayesStruct.resetSpeedSize(speedPriorValue * 200); @@ -177,25 +197,7 @@ noteOnMatches[i] = false; } -void midiEventHolder::clearAllEvents(){ - recordedNoteOnMatrix.clear(); - matchesFound.clear(); - noteOnMatches.clear(); - recordedEventTimes.clear(); - measureVector.clear(); - //played events: - playedEventTimes.clear(); - playedNoteOnMatrix.clear(); - matchMatrix.clear(); - bestMatchFound.clear(); - periodValues.clear(); - - beatPositions.clear(); - - recordedTotalNoteCounterByPitch.clear(); - recordedTotalNoteCounterByPitch.assign(127, 0); - totalNoteCounterIndex = 0; -} + void midiEventHolder::printNotes(){ printf("RECORDED MATRIX\n"); @@ -205,14 +207,8 @@ } -double midiEventHolder::getEventTimeTicks(double millis){ - return 0.0; - //return (millis * pulsesPerQuarternote / period); -} +#pragma mark -New Observed Event -double midiEventHolder::getEventTimeMillis(double ticks){ - return (period * ticks / (double) pulsesPerQuarternote); -} void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){ // tempoSpeedString = ""; @@ -322,6 +318,26 @@ } +double midiEventHolder::getEventTimeTicks(double millis){ + return 0.0; + //return (millis * pulsesPerQuarternote / period); +} + +double midiEventHolder::getEventTimeMillis(double ticks){ + return (period * ticks / (double) pulsesPerQuarternote); +} + + + +double midiEventHolder::getTimeNow(double eventTime){ + double timeNow = eventTime; + if (runningInRealTime) + timeNow = ofGetElapsedTimeMillis(); + return timeNow; +} + +#pragma mark -Tempo Update + void midiEventHolder::updateTempo(){ //having found matches we have matches for new note and matches for previous notes if (newOptimalMethod)//now true @@ -334,13 +350,6 @@ //bayesStruct.addGaussianNoiseToSpeedPosterior(10); } -double midiEventHolder::getTimeNow(double eventTime){ - double timeNow = eventTime; - if (runningInRealTime) - timeNow = ofGetElapsedTimeMillis(); - return timeNow; -} - int midiEventHolder::findLocalMatches(int notePitch){ //here we find the matches to the new note within appropriate range @@ -790,6 +799,7 @@ } } +#pragma mark -Position Update void midiEventHolder::updatePlayPosition(){ //timeDifference = ofGetElapsedTimeMillis() - startPlayingTime;//elpased @@ -1001,6 +1011,7 @@ } } +#pragma mark -Drawing void midiEventHolder::drawMidiFile(){ //ofBackground(80,80,80); @@ -1036,16 +1047,16 @@ ofSetColor(255,255,255); if (checkIfMatchedNote(tmpIndex)) ofSetColor(100,100,100);//0,0,255); - else if(noteOnMatches[tmpIndex]){ - ofSetColor(255,0,255);//pink + else if(noteOnMatches[tmpIndex] && !saveImage){ + ofSetHexColor(matchedColor);//pink } else{ ofSetColor(255,255,255);//255,255,255); } //ofSetColor(255,255,255); - if (tmpIndex == bestMatchIndex) - ofSetColor(255,0,0);//best recent match is in red + if (tmpIndex == bestMatchIndex && !saveImage) + ofSetHexColor(bestMatchedColor);//best recent match is in red // XXX replace ofgetwidth below //if (tmpIndex >= 0 && tmpIndex < size) @@ -1065,6 +1076,7 @@ //orange line at best estimate xLocation = getLocationFromMillis(bayesStruct.bestEstimate); ofSetColor(250,250,20);//250,100,0); + if (!saveImage) ofLine(xLocation, 0, xLocation, (*screenHeight)); @@ -1077,7 +1089,8 @@ //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)); + if (!saveImage) + ofLine(xLocation, 0, xLocation, (*screenHeight)); //lines where matching window start and end are ofSetColor(0);//0,100,255); @@ -1093,7 +1106,7 @@ while (tmpIndex < measureVector.size() && measureVector[tmpIndex] < (numberOfScreensIn+1)*ticksPerScreen){ int measureLocation = measureVector[tmpIndex]; int xLocation = (float)(measureLocation - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen; - ofSetColor(155,155,0); + ofSetColor(155,155,155); ofLine(xLocation, 0, xLocation, (*screenHeight)); tmpIndex++; } @@ -1107,6 +1120,8 @@ } //ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); + + if (printInfo){ ofSetColor(255,255,255); ofDrawBitmapString(timeString, 20, 60); string diffString = "diff "+ofToString(smoothDifference); @@ -1117,11 +1132,14 @@ diffString += "\nlast best est: "+ofToString(bayesStruct.lastBestEstimateUpdateTime, 0); 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); + if (!saveImage) + ofRect(0,yLocation, 100, noteHeight); @@ -1183,10 +1201,18 @@ void midiEventHolder::drawFile(){ - drawMidiFile(); + drawMidiFile(); + if (saveImage){ + std::string file = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/cleanMidiLayout.png"; + saveImageFile(file); + } + + + if (printInfo){ ofSetColor(0,0,255); ofDrawBitmapString("period"+ofToString(period, 2), ofGetWidth() - 180, 20); + } // bayesStruct.drawArrays(); @@ -1195,11 +1221,16 @@ //need to draw arrays within correct timescope if (drawPhaseMode) - bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); + bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); if (drawTempoMode) bayesStruct.drawTempoArrays(); + if (saveImage){ + std::string file = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/distbnMidiLayout.png"; + saveImageFile(file); + saveImage = false; + } ofSetColor(0, 0, 0); //ofDrawBitmapString(matchString, 20, ofGetHeight() - 20); @@ -1220,6 +1251,10 @@ } + + + + void midiEventHolder::drawInterNoteIntervals(){ ofSetColor(0,0,150); @@ -1238,6 +1273,58 @@ } +#pragma mark -saveDistributionsAsTextFile + +void midiEventHolder::writeAllDistributions(){ + std::string file = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/priorDistbnOut.txt"; + writeDistribution(bayesStruct.prior, file); + file = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/likelihoodDistbnOut.txt"; + writeDistribution(bayesStruct.likelihood, file); + file = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/posteriorDistbnOut.txt"; + writeDistribution(bayesStruct.posterior, file); + + saveImage = true; + +} + +void midiEventHolder::saveImageFile(std::string file){ + img.grabScreen(0, 0, ofGetWidth(), ofGetHeight()); + img.saveImage(file); +} + + +void midiEventHolder::writeDistribution(DynamicVector& distribution, std::string file){ + + dataWriter.openFile(file); + + double startTimeMillis = timeOffsetForScreen; + double endTimeMillis = timeOffsetForScreen + getEventTimeMillis(ticksPerScreen); + + int startArrayIndex = 0; + + if (distribution.getIndexInRealTerms(distribution.arraySize-1) > startTimeMillis){ + //i.e. the array is on the page + + while (distribution.getIndexInRealTerms(startArrayIndex) < startTimeMillis){ + startArrayIndex++; + } + } + + int endArrayIndex = distribution.arraySize-1; + //could find constraints here + if (distribution.getIndexInRealTerms(distribution.arraySize-1) > endTimeMillis) + endArrayIndex = (floor)((endTimeMillis - distribution.offset)/distribution.scalar); + + + + for (int i = startArrayIndex;i <= endArrayIndex;i++){ + dataWriter.writeValue(distribution.getIndexInRealTerms(i), distribution.array[i]); + } + dataWriter.closeFile(); + + +} + void midiEventHolder::printInterNoteIntervals(){
--- a/jnmr/midiEventHolder.h Sat Mar 31 14:04:49 2012 +0100 +++ b/jnmr/midiEventHolder.h Tue Jul 17 22:13:10 2012 +0100 @@ -12,6 +12,8 @@ #include "ofMain.h" #include "BayesianArrayStructure.h" #include "Annotations.h" +#include "OutputDataWriter.h" + class midiEventHolder{ @@ -198,5 +200,14 @@ double outputPosition;//debug variable void testSpeedPriorSetting(); + + bool printInfo; + OutputDataWriter dataWriter; + void writeAllDistributions(); + void writeDistribution(DynamicVector& distribution, std::string file); + ofImage img; + void saveImageFile(std::string file); + bool saveImage; + }; #endif \ No newline at end of file
--- a/jnmr/testApp.cpp Sat Mar 31 14:04:49 2012 +0100 +++ b/jnmr/testApp.cpp Tue Jul 17 22:13:10 2012 +0100 @@ -5,6 +5,7 @@ this->args = args; } +#pragma mark -Initialise //-------------------------------------------------------------- void testApp::setup(){ @@ -98,7 +99,7 @@ } - +#pragma mark -Update //-------------------------------------------------------------- void testApp::update(){ if (playing){ @@ -369,19 +370,19 @@ // cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << pitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl; } +#pragma mark -Draw + //-------------------------------------------------------------- void testApp::draw(){ midiEvents.drawFile(); - +/* string info = "Measure "; info += ofToString(lastMeasureSent); info += " Last note "; - info += ofToString(lastScoreIndexSent); - - ofSetHexColor(0xFF0000); -// ofDrawBitmapString(info, 20, 20); - + info += ofToString(lastScoreIndexSent); + ofDrawBitmapString(info, 20, 20); +*/ midiEvents.drawMidiFile(noteInStream.midiInputEvents); //drawMuseScoreText(); @@ -408,6 +409,7 @@ verdana30.drawString(ratingString, 20, 60); } +#pragma mark -keyInput //-------------------------------------------------------------- void testApp::keyPressed(int key){ @@ -435,8 +437,6 @@ printf("CROSS UPDATE TOOK %f", timenow); } - if (key == 'x') - sendNoteDataByOsc(60, 0); if (key == OF_KEY_LEFT){ @@ -519,8 +519,20 @@ loadRecordedMidiFile(); } + if (key == 'v'){ + midiEvents.bayesStruct.drawPrior = midiEvents.bayesStruct.drawPosterior; + midiEvents.bayesStruct.drawLikelihood = !midiEvents.bayesStruct.drawLikelihood; + midiEvents.bayesStruct.drawPrior = !midiEvents.bayesStruct.drawPrior; + midiEvents.bayesStruct.drawPosterior = !midiEvents.bayesStruct.drawPosterior; + } + if (key == 'x'){ + midiEvents.bayesStruct.drawPrior = !midiEvents.bayesStruct.drawPrior; + } + if (key == 'g'){ + midiEvents.writeAllDistributions(); + } } void testApp::loadRecordedMidiFile(){
--- a/matchAnnotationSrc/testApp.cpp Sat Mar 31 14:04:49 2012 +0100 +++ b/matchAnnotationSrc/testApp.cpp Tue Jul 17 22:13:10 2012 +0100 @@ -4,7 +4,14 @@ 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/completeTestsTempoMAPestimate/rwcOutputData_RM-C0"; + jnmrPlayerRoot = "/Users/andrew/Documents/work/programming/of_preRelease_v007_osx/apps/myOpenFrameworks007/JNMR_MidiFollower/bin/data/FilesOut/"; + +//set which parameter set to test + jnmrPlayerRoot += "rwc_output_likelihood0pt6";//width 100ms +// jnmrPlayerRoot += "rwcOutput_likelihood0pt8_width50"; +// jnmrPlayerRoot += "completeTestsTempoMAPestimate_likelihood0pt2"; + + jnmrPlayerRoot += "/rwcOutputData_RM-C0"; // matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/MatchAudioToMidiOutput/RWCmatch_RM-C";//ACTUAL AUDIO VERSION OF WARPED matchRoot = "/Users/andrew/Documents/work/programming/Shell Scripts/MatchMidiToMidiOutput/RWCmatch_RM-C";//MIDI VERSION OF WARPED @@ -278,18 +285,10 @@ total /= count; std::sort(diffVec.begin(), diffVec.end());//sort vector - - /* printf("SORTED TWO HUNDRED\n"); - - for (int i = 0;i < diffVec.size() ;i++){ - printf("Sort[%i] : %f\n", i, diffVec[i]); - } - */ - 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; + printf("Count %i Median %3.1f, mean is %3.1f\n", count, diffVec[(int)(diffVec.size()/2)], total); for (int i = 0;i < 7;i++){ t.percentiles[i] = t.percentileCount[i] / count;