Mercurial > hg > midi-score-follower
changeset 4:4a8e6a6cd224
optimised draw function in dynamic vector class. Added Gaussian lookup but not yet used.
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Fri, 19 Aug 2011 15:53:04 +0100 |
parents | de86d77f2612 |
children | 195907bb8bb7 |
files | src/BayesianArrayStructure.cpp src/BayesianArrayStructure.h src/CannamMidiFileLoader.cpp src/DynamicVector.cpp src/DynamicVector.h src/midiEventHolder.cpp |
diffstat | 6 files changed, 119 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/src/BayesianArrayStructure.cpp Fri Aug 19 02:36:34 2011 +0100 +++ b/src/BayesianArrayStructure.cpp Fri Aug 19 15:53:04 2011 +0100 @@ -30,6 +30,7 @@ tmpPrior.translateDistribution(20); */ tmpBestEstimate = 0; + crossUpdateTimeThreshold = 100; } BayesianArrayStructure::BayesianArrayStructure(int length){ @@ -250,38 +251,70 @@ double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar; + prior.zero();//kill prior calculateNewPriorOffset(timeDifference);//set new prior offset here - for (int i = 0;i < speed.arraySize;i++){ -// printf("[%i] %f\n", i, speed.array[i]); - //set speed - double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5 + if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold) + complexCrossUpdate(timeDifferenceInPositionVectorUnits); + else + translateByMaximumSpeed(timeDifferenceInPositionVectorUnits); + - //so we have moved - int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value - - if (speed.array[i] != 0){ - - // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits); - - for (int postIndex = 0;postIndex < position.arraySize;postIndex++){ - //old posterior contributing to new prior - int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved; - if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){ - prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]); - // printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]); - } - - } - - }//if not zero - }//end speed updateCounter++; prior.renormalise(); } +void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){ + int distanceMoved, newPriorIndex; + for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){ + + double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5 + + //so we have moved + distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value + + if (relativeSpeedPosterior.array[i] != 0){ + double speedContribution = relativeSpeedPosterior.array[i]; + // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits); + + for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){ + //old posterior contributing to new prior + newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved; + if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){ + prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution); + } + + } + + }//if not zero + }//end speed +} + + + +void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){ + int distanceMoved, newPriorIndex; + + + double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);//using max value only + //so for scalar 0.01, 50 -> speed value of 0.5 + double speedContribution = relativeSpeedPosterior.array[relativeSpeedPosterior.MAPestimate]; + //so we have moved + distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value + // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits); + + for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){ + //old posterior contributing to new prior + newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved; + if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){ + prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution); + } + + } + +} void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(const double& std_dev){ tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
--- a/src/BayesianArrayStructure.h Fri Aug 19 02:36:34 2011 +0100 +++ b/src/BayesianArrayStructure.h Fri Aug 19 15:53:04 2011 +0100 @@ -84,8 +84,12 @@ void updateTempoLikelihood(const double& speedRatio, const double& matchFactor); void crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference); + void complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits); + void translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits); + double crossUpdateTimeThreshold;//time after which we do complex update of multiple speeds double speedPriorValue; + }; #endif
--- a/src/CannamMidiFileLoader.cpp Fri Aug 19 02:36:34 2011 +0100 +++ b/src/CannamMidiFileLoader.cpp Fri Aug 19 15:53:04 2011 +0100 @@ -147,12 +147,12 @@ switch (j->getMessageType()) { case MIDI_NOTE_ON: - cout << t << ": Note: channel " << ch + /* cout << t << ": Note: channel " << ch << " duration " << j->getDuration() << " pitch " << j->getPitch() << " velocity " << j->getVelocity() << "event time " << myMidiEvents.getEventTimeMillis(t) << endl; - + */ if (noteOnIndex == 0){ firstNoteTime = myMidiEvents.getEventTimeMillis(t); @@ -177,7 +177,7 @@ myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t)); else { myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t) - firstNoteTime); - printf("chopping beginning %f \n", myMidiEvents.getEventTimeMillis(t) - firstNoteTime); + // printf("chopping beginning %f \n", myMidiEvents.getEventTimeMillis(t) - firstNoteTime); } break;
--- a/src/DynamicVector.cpp Fri Aug 19 02:36:34 2011 +0100 +++ b/src/DynamicVector.cpp Fri Aug 19 15:53:04 2011 +0100 @@ -17,6 +17,14 @@ MAPestimate = 0; offset = 0; scalar = 1; + + gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2; + gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16); + double factor = 1.0;//(1.0 / (gaussianLookupStdDev*sqrt(2*PI)) );//1.0;//-1.0/(2*PI*sqrt(gaussianLookupStdDev)); + for (int i = 0;i < GAUSSIAN_LOOKUP_LENGTH;i++){ + gaussianLookupTable[i] = factor*exp(-1.0*(i-gaussianLookupMean)*(i-gaussianLookupMean)/(2.0*gaussianLookupStdDev*gaussianLookupStdDev)); + } + } void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){ @@ -113,14 +121,42 @@ } void DynamicVector::addGaussianShape(double mean, double StdDev, double factor){ + int i; factor *= (1/(StdDev*sqrt(2*PI))); for (i=0;i<array.size();i++){ array[i] += factor*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); } + + //addGaussianShapeByLookupTable(mean, StdDev, factor); +} + +void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor){ + int i; + int lookupIndex ; + factor *= (1/(StdDev*sqrt(2*PI))); + for (i=0;i<array.size()-1;i++){ + lookupIndex = round(getLookupIndex(i, mean, StdDev)); + array[i] += factor*gaussianLookupTable[lookupIndex]; + } //printf("ADDED GAUSSIAN SHAPE %i\n", (int)array.size()); } +double DynamicVector::getLookupIndex(const int& i, const double& mean, const double& StdDev){ + + double Z = ((double)i - mean)/StdDev; + double lookupIndex = Z*gaussianLookupStdDev + gaussianLookupMean; + + if (lookupIndex < 0) + lookupIndex = 0; + + if (lookupIndex >= GAUSSIAN_LOOKUP_LENGTH) + lookupIndex = GAUSSIAN_LOOKUP_LENGTH-1; + +// (i - mean)*(i-mean)*(GAUSSIAN_LOOKUP_LENGTH*GAUSSIAN_LOOKUP_LENGTH/16.0)/(StdDev*StdDev); + return lookupIndex; +} + void DynamicVector::addTriangularShape(double mean, double width, double factor){ int i; @@ -172,9 +208,15 @@ double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); double screenHeight = ofGetHeight(); double maxVal = getMaximum(); - - for (int i = max(1,minIndex+1);i < min(maxIndex, (int)array.size());i++){ - ofLine (stepSize*(i-1), screenHeight * (1 - array[i-1] / maxVal), stepSize*i, screenHeight * (1 - array[i] / maxVal) ); + int startInt = max(1,minIndex+1); + int endInt = min(maxIndex, (int)array.size()); + double heightConstant = screenHeight / maxVal; + int lastHeightPixel = heightConstant * (1 - array[startInt-1]); + int newHeightPixel; + for (int i = startInt;i < endInt;i++){ + newHeightPixel = (int) heightConstant * (1 - array[i]); + ofLine (stepSize*(i-1), lastHeightPixel, stepSize*i, newHeightPixel); + lastHeightPixel = newHeightPixel; } }
--- a/src/DynamicVector.h Fri Aug 19 02:36:34 2011 +0100 +++ b/src/DynamicVector.h Fri Aug 19 15:53:04 2011 +0100 @@ -14,6 +14,7 @@ #ifndef _DYNAMIC_VECTOR #define _DYNAMIC_VECTOR +#define GAUSSIAN_LOOKUP_LENGTH 1000000 class DynamicVector{ public: @@ -26,6 +27,11 @@ DoubleVector array; double getMaximum(); double getIntegratedEstimate(); + double getLookupIndex(const int& i, const double& mean, const double& StdDev); + void addGaussianShapeByLookupTable(double& mean, double& StdDev, double& factor); + double gaussianLookupTable[GAUSSIAN_LOOKUP_LENGTH]; + double gaussianLookupMean, gaussianLookupStdDev; + void drawVector(const int& minIndex, const int& maxIndex); void drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex);
--- a/src/midiEventHolder.cpp Fri Aug 19 02:36:34 2011 +0100 +++ b/src/midiEventHolder.cpp Fri Aug 19 15:53:04 2011 +0100 @@ -25,13 +25,13 @@ noteMinimum = 30; noteMaximum = 96; - minimumMatchSpeed = 0.7; - maximumMatchSpeed = 1.3; + minimumMatchSpeed = 0.0; + maximumMatchSpeed = 2.0; likelihoodWidth = 100; likelihoodToNoiseRatio = 0.02; - bayesStruct.speedLikelihoodNoise = 0.05;//was 0.05 + bayesStruct.speedLikelihoodNoise = 0.02;//was 0.05 bayesStruct.speedDecayWidth = 20; bayesStruct.speedDecayAmount = 10; @@ -49,6 +49,8 @@ speedPriorValue = 1.0; noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum); + + 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)]); }