Mercurial > hg > midi-score-follower
changeset 30:be2e779d76b5
internote calculation added but not running. Better way of waiting for first note to happen before starting.
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Wed, 07 Dec 2011 13:04:59 +0000 |
parents | 69083ce48b83 |
children | 9a70d9abdc8b |
files | .DS_Store hackday/BayesianArrayStructure.cpp hackday/CannamMidiFileLoader.cpp hackday/midiEventHolder.cpp hackday/midiEventHolder.h hackday/testApp.cpp hackday/testApp.h |
diffstat | 7 files changed, 147 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/hackday/BayesianArrayStructure.cpp Mon Dec 05 21:47:19 2011 +0000 +++ b/hackday/BayesianArrayStructure.cpp Wed Dec 07 13:04:59 2011 +0000 @@ -14,7 +14,7 @@ BayesianArrayStructure::BayesianArrayStructure(){ printf("Bayesian structure: DeFault constructor called"); - usingIntegratedTempoEstimate = false;// use max index + usingIntegratedTempoEstimate = true;// use max index relativeSpeedLikelihoodStdDev = 5.0;
--- a/hackday/CannamMidiFileLoader.cpp Mon Dec 05 21:47:19 2011 +0000 +++ b/hackday/CannamMidiFileLoader.cpp Wed Dec 07 13:04:59 2011 +0000 @@ -284,6 +284,8 @@ if (printMidiInfo) myMidiEvents.printRecordedEvents(); + printf("Duration of MIDI file is %f \n", myMidiEvents.recordedEventTimes[myMidiEvents.recordedEventTimes.size()-1]); + //printMeasuresSoFar(myMidiEvents); }//end cannam midi main
--- a/hackday/midiEventHolder.cpp Mon Dec 05 21:47:19 2011 +0000 +++ b/hackday/midiEventHolder.cpp Wed Dec 07 13:04:59 2011 +0000 @@ -17,6 +17,10 @@ useTempoPrior = false;//puts sine wave round tempo confidenceWeightingUsed = true; + newOptimalMethod = true; + + interNoteRange = 1600;//preferred duration + //so max here is really four //there is option to use MAP estinate or integral in beayesianarraystricture class @@ -63,11 +67,19 @@ //bayesStruct.simpleExample(); - speedWindowWidthMillis = matchWindowWidth;// 4000; + speedWindowWidthMillis = 4000; speedPriorValue = 1.0; noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum); + intervalsToCheck.push_back(1); + intervalsToCheck.push_back(2); + //intervalsToCheck.push_back(3); + intervalsToCheck.push_back(4); + intervalsToCheck.push_back(6); + intervalsToCheck.push_back(8); + intervalsToCheck.push_back(16); + drawPhaseMode = true; @@ -97,10 +109,12 @@ recordedTotalNoteCounterByPitch.assign(127,0); totalNoteCounterIndex = 0; + interNoteIntervals.clear(); bayesStruct.resetSpeedToOne(); bayesStruct.setSpeedPrior(speedPriorValue); setMatchedNotesBackToFalse(); + } void midiEventHolder::setMatchedNotesBackToFalse(){ @@ -237,21 +251,22 @@ setMatchLikelihoods(numberOfMatchesFound); bayesStruct.calculatePosterior(); + if (recordedEventTimes.size() > 0){ updateTempo(); - - + //calcuateNewInterNoteIntervals(); + } } void midiEventHolder::updateTempo(){ //having found matches we have matches for new note and matches for previous notes -/* - if (!confidenceWeightingUsed) + if (newOptimalMethod) + findOptimumTempoPairsToCurrentBestMatch(); + else if (!confidenceWeightingUsed) findLocalTempoPairs(); else findLocalTempoPairsWeightedForConfidence(); -*/ - findOptimumTempoPairsToCurrentBestMatch(); + //bayesStruct.addGaussianNoiseToSpeedPosterior(10); } @@ -596,14 +611,14 @@ //change this so we start first in window and go to end - while (checkRecordedCurrentIndex >= 0 && recordedEventTimes[checkRecordedCurrentIndex] > recordedTimeOfBestMatch - speedWindowWidthMillis ){ + while (checkRecordedCurrentIndex >= 0 && recordedEventTimes[checkRecordedCurrentIndex] > recordedTimeOfBestMatch - matchWindowWidth){ checkRecordedCurrentIndex--; } double bestSpeedEstimate = getBestSpeedEstimate(currentPlayedIndex, bestMatchIndex); - while (checkRecordedCurrentIndex < recordedEventTimes.size() && recordedEventTimes[checkRecordedCurrentIndex] < recordedTimeOfBestMatch + speedWindowWidthMillis ){ + while (checkRecordedCurrentIndex < recordedEventTimes.size() && recordedEventTimes[checkRecordedCurrentIndex] < recordedTimeOfBestMatch + matchWindowWidth ){ if (recordedNoteOnMatrix[checkRecordedCurrentIndex][1] == currentPlayedPitch ){ checkRecordedPreviousIndex = checkRecordedCurrentIndex; double recordedTimeCurrent = recordedEventTimes[checkRecordedCurrentIndex] ; @@ -672,6 +687,40 @@ } +void midiEventHolder::calcuateNewInterNoteIntervals(){ + DoubleVector v; + + int currentPlayedIndex = playedNoteOnMatrix.size()-1; +// int recordedCurrentIndex = bestMatchFound[currentPlayedIndex]; + int previousIndex = currentPlayedIndex-1; + + //withing speedwindow i.e. 4 seconds + while (previousIndex >= 0 && playedEventTimes[previousIndex] + interNoteRange > playedEventTimes[currentPlayedIndex]) { + + double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; + + checkForCorrectInterval(playedTimeDifference, &v); + + previousIndex--; + } + + if (v.size() > 0) + interNoteIntervals.push_back(v); + //printf("\n"); +} + +void midiEventHolder::checkForCorrectInterval(const double& playedTimeDifference, DoubleVector* v){ + double intervalDuration = 0.0; + + for (int intervalIndex = 0;intervalIndex < 3;intervalIndex++){ + //on;y check 1,2 and 4 + double possibleDuration = playedTimeDifference / intervalsToCheck[intervalIndex]; + if (possibleDuration >= 200 && possibleDuration < 400){ + v->push_back(possibleDuration); + // printf("int %f / %i :: %f ", playedTimeDifference, intervalsToCheck[intervalIndex], possibleDuration); + } + } +} /* void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){ @@ -981,8 +1030,44 @@ string infostring = "speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 3); ofDrawBitmapString(infostring, 20 , ofGetHeight() - 60); */ + + //drawInterNoteIntervals(); + } +void midiEventHolder::drawInterNoteIntervals(){ + + ofSetColor(0,0,150); + int size = interNoteIntervals.size(); + int numberToShow = min(100, size); + double x ; + for (int y = 1;y < numberToShow;y++){ + for (int point = 0;point < interNoteIntervals[y].size();point++){ + double interval = interNoteIntervals[size - y][point]; + x = interval - 200; + x *= (*screenWidth) / 200.0; + } + double h = (double)(y * (*screenHeight)) / numberToShow; + ofCircle(x, h, 5); + } + +} + + +void midiEventHolder::printInterNoteIntervals(){ + + int size = interNoteIntervals.size(); + int numberToShow = 20; + double x ; + for (int y = max(0, size - numberToShow);y < interNoteIntervals.size();y++){ + for (int point = 0;point < interNoteIntervals[y].size();point++){ + printf("[%i][%i] : %f", y, point, interNoteIntervals[y][point]); + } + printf("\n"); + } + +} + int midiEventHolder::getLocationFromTicks(double tickPosition){ return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen); }
--- a/hackday/midiEventHolder.h Mon Dec 05 21:47:19 2011 +0000 +++ b/hackday/midiEventHolder.h Wed Dec 07 13:04:59 2011 +0000 @@ -83,6 +83,9 @@ void findOptimumTempoPairsToCurrentBestMatch(); double getBestSpeedEstimate(const int& currentPlayedIndex, const int& equivalentRecordedIndex); + + void calcuateNewInterNoteIntervals(); + double likelihoodWidth; double likelihoodToNoiseRatio; @@ -153,7 +156,12 @@ double ticksFactor; - - + bool newOptimalMethod; + DoubleMatrix interNoteIntervals; + IntVector intervalsToCheck; + void checkForCorrectInterval(const double& playedTimeDifference, DoubleVector* v); + void drawInterNoteIntervals(); + void printInterNoteIntervals(); + int interNoteRange; }; #endif \ No newline at end of file
--- a/hackday/testApp.cpp Mon Dec 05 21:47:19 2011 +0000 +++ b/hackday/testApp.cpp Wed Dec 07 13:04:59 2011 +0000 @@ -52,7 +52,7 @@ verdana30.setLetterSpacing(1.035); playing = false; - + readyToStart = true; receiver.setup( PORT ); @@ -95,6 +95,11 @@ double time = m.getArgAsFloat(2); if (velocity != 0){ + if (readyToStart){ + startPlaying(); + printf("starting to PLAY!!!"); + } + midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time); noteInStream.newNoteCounted(newMidiOnPitch); } @@ -111,7 +116,7 @@ if ( m.getAddress() == "/startplaying" ) { - startPlaying(); + prepareToStartOnNextNote(); } if ( m.getAddress() == "/stopplaying" ) @@ -154,7 +159,7 @@ } }//end while osc - + if (midiEvents.recordedEventTimes.size() > 0) checkNewScoreNote(); } @@ -198,10 +203,12 @@ } void testApp::sendNoteToMuseScore(){ + if (midiEvents.recordedNoteOnMatrix.size() > 0){ int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0]; int pitch = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][1]; printf("sending to muse score %i, %i \n", ticks, pitch); - + sendNoteDataByOsc(pitch, ticks); + } /* ofxOscMessage m; m.setAddress( "/plugin" ); @@ -210,7 +217,7 @@ m.addStringArg( noteString); sender.sendMessage( m ); */ - sendNoteDataByOsc(pitch, ticks); + // /color-note 60,3440 @@ -333,10 +340,7 @@ midiPort--; midiIn.openPort(midiPort); } - -// if (key == ' '){ -// startPlaying(); -// } + if (key == '-') transpose -= 12; @@ -378,6 +382,11 @@ sendBlackNotes(); } + + if (key == 'n'){ + midiEvents.printInterNoteIntervals(); + } + if (key == OF_KEY_DOWN){ if (midiEvents.ticksPerScreen >= 4000) midiEvents.ticksPerScreen -= 2000; @@ -397,7 +406,9 @@ } if (key == 'l') - midiEvents.bayesStruct.decaySpeedDistribution(100); + + + //midiEvents.bayesStruct.decaySpeedDistribution(100); if (key == 't') midiEvents.drawTempoMode = !midiEvents.drawTempoMode; @@ -418,20 +429,24 @@ } if (key == 'o' || key == 'O'){ - //open audio file - string *filePtr; - filePtr = &midiFileName; - - if (getFilenameFromDialogBox(filePtr)){ - printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str()); - cannamMainFunction(); - } + loadRecordedMidiFile(); } } +void testApp::loadRecordedMidiFile(){ + //open audio file + string *filePtr; + filePtr = &midiFileName; + + if (getFilenameFromDialogBox(filePtr)){ + printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str()); + cannamMainFunction(); + } +} + //-------------------------------------------------------------- void testApp::keyReleased(int key){ @@ -465,6 +480,9 @@ } +void testApp::prepareToStartOnNextNote(){ + readyToStart = true; +} void testApp::startPlaying(){ @@ -473,6 +491,7 @@ noteInStream.reset(); midiEvents.setStartPlayingTimes(); sendBlackNotes(); + readyToStart = false; //this is where we stop and start playing }