Mercurial > hg > midi-score-follower
view src/DynamicBayesianArray.cpp @ 5:195907bb8bb7
added purple where notes have been seen - lets you see what updates have been used. Also the chopping of midi files to the beginning was introduced recently, so when they load, you chop any white space at the beginning, then use first note to launch.
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Fri, 19 Aug 2011 16:38:30 +0100 |
parents | b299a65a3ad0 |
children |
line wrap: on
line source
/* * DynamicDynamicBayesianArray.cpp * midiCannamReader * * Created by Andrew on 17/07/2011. * Copyright 2011 QMUL. All rights reserved. * */ #include "DynamicBayesianArray.h" #include "math.h" #include "ofMain.h" DynamicBayesianArray::DynamicBayesianArray(){ // prior.createVector(240); // likelihood.createVector(240); // posterior.createVector(240); testVector.createVector(240); testVector.addGaussianShape(100,10, 0.1); likelihoodNoise = 0.5; likelihoodMean = ARRAY_SIZE/2; likelihoodStdDev = ARRAY_SIZE / 12; initialiseArray(); } void DynamicBayesianArray::initialiseArray(){ //maximumIndex = 12;//change this setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1); setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev); calculatePosterior(); renormalisePosterior(); posteriorDecayRate = 0.06; eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4 earlySixteenthNoteProportion = 0; lateSixteenthNoteProportion = 0; decayNoiseAmount = 0.1; decayNoiseStdDev = ARRAY_SIZE/24; standardDeviation = likelihoodStdDev; setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev); setGaussianLikelihood(likelihoodMean, likelihoodStdDev); } void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); //posterior[i] = prior[i]; } } void DynamicBayesianArray::setGaussianPosterior(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); } } void DynamicBayesianArray::setGaussianLikelihood(float mean, float StdDev){ if (mean >= 0 && mean <= ARRAY_SIZE){ int i; float eighthDifference; int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; float mainDifference; float gaussianProportion = 1 - likelihoodNoise; for (i=0;i < ARRAY_SIZE;i++){ mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean)); //without * (1 - eighthNoteProportion) likelihood[i] = gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; likelihood[i] += (likelihoodNoise / ARRAY_SIZE); //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , //(double) (likelihoodNoise / ARRAY_SIZE) ); } // renormaliseArray(&likelihood[0], ARRAY_SIZE); }//end if mean within limits } void DynamicBayesianArray::calculatePosterior(){ int i; for (i=0;i < ARRAY_SIZE;i++){ posterior[i] = likelihood[i] * prior[i]; } //renormalisePosterior(); } float DynamicBayesianArray::getMaximum(float *ptr, int length){ int i; float max = 0; for (i=0;i < length;i++){ if (*(ptr+i)>max) max = *(ptr+i); } maximumValue = max; return max; } float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){ float returnArray[2]; int i; float max = 0; maximumIndex = 0; for (i=0;i < length;i++){ if (*(ptr+i)>max){ max = *(ptr+i); maximumIndex = i; } } returnArray[0] = max; returnArray[1] = maximumIndex; maximumValue = max; return &returnArray[0]; } double DynamicBayesianArray::getIntegratedEstimateIndex(){ int i; float integratedQuantity = 0; float integratedTotal = 0; double integratedIndex = 0; for (i=0;i < ARRAY_SIZE;i++){ integratedQuantity += posterior[i];//the values of the probability distribution integratedTotal += i*posterior[i]; } if (integratedQuantity > 0){ integratedIndex = integratedTotal / integratedQuantity; } integratedEstimate = (float) integratedIndex; return integratedIndex; } double DynamicBayesianArray::calculateStandardDeviation(){ double total = 0; double pdfSum; double variance = 0; for (int i=0;i < ARRAY_SIZE;i++){ //*posterior[i] * total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution pdfSum += posterior[i]; } if (pdfSum > 0) variance = total / pdfSum; else variance = ARRAY_SIZE; standardDeviation = sqrt(variance); return standardDeviation; } void DynamicBayesianArray::renormaliseArray(float *ptr, int length){ int i; float totalArea = 0; for (i=0;i < length;i++){ totalArea += *(ptr+i); } for (i=0;i < length;i++){ *(ptr+i) /= totalArea; } } void DynamicBayesianArray::resetPrior(){ int i; for (i=0;i<ARRAY_SIZE;i++){ prior[i] = posterior[i]; } } void DynamicBayesianArray::renormalisePosterior(){ int i; float totalArea = 0; for (i=0;i < ARRAY_SIZE;i++){ totalArea += posterior[i]; } for (i=0;i < ARRAY_SIZE;i++){ posterior[i] /= totalArea; } } void DynamicBayesianArray::decayPosterior(){ float *pointer; pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE); float maximum; maximum = *pointer; int i; for (i=0;i<ARRAY_SIZE;i++){ posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value } maximumIndex = *(pointer+1); } void DynamicBayesianArray::setDecayNoiseGaussian(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); } } void DynamicBayesianArray::decayPosteriorWithGaussianNoise(){ int i; float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE); for (i=0;i<ARRAY_SIZE;i++){ posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount; //posteriorDecayRate * 0.01;;//usded to be * maximum not minus value } } void DynamicBayesianArray::resetMaximumPosterior(){ int i; float max = 0; for (i=0;i < ARRAY_SIZE;i++){ if (posterior[i]>max){ maximumIndex = i; max = posterior[i]; } } } void DynamicBayesianArray::translateDistribution(int translationIndex){ int tmpIndex; //copy array int i; for (i=0;i < ARRAY_SIZE;i++){ tempPosteriorArray[i] = posterior[i] ; } //translate values for (i=0;i < ARRAY_SIZE;i++){ tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE; posterior[tmpIndex] = tempPosteriorArray[i]; } //now delete tmp array } void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){ if (minIndex >= 0){ double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); double screenHeight = ofGetHeight(); double maxVal = getMaximum(&arrayToDraw[0], maxIndex); for (int i = minIndex+1;i < maxIndex;i++){ ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) ); } } } /* void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){ if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0)) } */ /* void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){ //this has eighth and sixteenth positions included if (mean >= 0 && mean <= ARRAY_SIZE){ int i; float eighthDifference; int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;; int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;; float mainDifference, sixteenthDifference; float gaussianProportion = 1 - likelihoodNoise; float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion); for (i=0;i < ARRAY_SIZE;i++){ mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean)); likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition); eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ; sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition); sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition); sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; likelihood[i] += (likelihoodNoise / ARRAY_SIZE); //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , //(double) (likelihoodNoise / ARRAY_SIZE) ); } // renormaliseArray(&likelihood[0], ARRAY_SIZE); }//end if mean within limits } */