andrew@2: #include "testApp.h" andrew@2: andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: //relooking at this problem andrew@2: //bayesianTempo7 - have had working well with Bayesian8NEW maxmsp set andrew@2: andrew@2: //updated in bayesian8 andrew@2: //integrate so that maxPhase and tempo are the integrated result across the pdf andrew@2: //rather tahn the maximum index - tends to reflect the actuial distribution better andrew@2: //and is the "correct" bayesian method andrew@2: andrew@2: //added [ and ] tpo change the alignment when rescue is needed andrew@2: andrew@2: //in Bayesian9 (BayesianTest8NEW) andrew@2: //added noise in phase process andrew@2: //started probability distribution for observed beat events andrew@2: andrew@2: //in bayesian 11 andrew@2: //get s.d. of posterior andrew@2: //this is set to be used as the s.d. of the likelihood andrew@2: andrew@2: andrew@2: //Initialiser : the algorithm has an initialisation stage with flat prior that detects liekly tempo andrew@2: andrew@2: andrew@2: andrew@2: //BAYESIAN DISTRIBUTION SET by class BayesianArray andrew@2: //SETUP - initialises array andrew@2: //UPDATE - decay the distribution with noise andrew@2: //this should be done using tempo and noise andrew@2: //DRAW - Draw current distributions and also the maximum andrew@2: andrew@2: //Runs with bayesian11NEW andrew@2: //and B-KeeperOldBayesianTestNew in Live andrew@2: //Needs - categorisation of beats and tempo andrew@2: //can we use our distribution to filter the input or is that cheating? andrew@2: andrew@2: //INtroduce lock scheme for tempo - we know where the beat fell, so can calculate the appropriate tempo interval andrew@2: andrew@2: void testApp::setup(){ andrew@9: andrew@10: outputFile.open("../../../data/baydrumTest.txt"); andrew@9: andrew@2: // listen on the given port andrew@2: cout << "listening for osc messages on port " << PORT << "\n"; andrew@2: receiver.setup( PORT ); andrew@2: andrew@2: // sender.setup( HOST, OUTPORT ); andrew@2: ofSetCircleResolution(50); andrew@2: ofBackground(255,255,255); andrew@2: bSmooth = false; andrew@2: msg_string = "setup"; andrew@2: andrew@2: ofSetWindowTitle("Bayesian Test"); andrew@2: andrew@2: ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps. andrew@2: andrew@2: KLdiv = 0; andrew@3: entropy = 0; andrew@2: andrew@2: hidePriorMode = false; andrew@2: andrew@2: printInterval = true; andrew@2: drawData = false; andrew@2: andrew@2: screenToDraw = 0; andrew@2: andrew@2: ofSetLineWidth(2); andrew@2: ofEnableSmoothing(); andrew@2: andrew@2: andrew@2: bSnapshot = false; andrew@2: snapCounter = 0; andrew@2: andrew@2: drumTracker.paused = false; andrew@2: andrew@2: // setDistributionOnStartTempo = true; andrew@2: andrew@2: resetParameters(); andrew@2: andrew@10: arrayToMsecScaleFactor = (drumTracker.tempoMaximum - drumTracker.tempoMinimum)/ drumTracker.arraySize;//turns array into ms andrew@2: tempoWindowMinimum = 100; andrew@2: tempoWindowMaximum = 150; andrew@2: tempoWindowWidth = 50; andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::resetParameters(){ andrew@2: andrew@2: } andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::update(){ andrew@2: andrew@2: andrew@2: updateOSCmessages(); andrew@2: andrew@2: //update tempo window range - this for viewing tempo closeup andrew@2: while (tempoWindowMinimum + tempoWindowWidth/4 > drumTracker.tempoDistribution.integratedEstimate) andrew@2: tempoWindowMinimum -= tempoWindowWidth/4; andrew@2: andrew@2: while (tempoWindowMinimum + 3*tempoWindowWidth/4 < drumTracker.tempoDistribution.integratedEstimate) andrew@2: tempoWindowMinimum += tempoWindowWidth/4; andrew@2: andrew@2: tempoWindowMaximum = tempoWindowMinimum + tempoWindowWidth; andrew@2: andrew@2: drumTracker.decayDistributions(); andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::updateOSCmessages(){ andrew@2: andrew@2: andrew@2: // check for waiting messages andrew@2: while( receiver.hasWaitingMessages() ) andrew@2: { andrew@2: ofxOscMessage m; andrew@2: receiver.getNextMessage( &m ); andrew@2: string newAddress = m.getAddress(); andrew@2: andrew@2: if ( m.getAddress() == "/Reset" ){ andrew@2: printf("baysian reset\n"); andrew@2: drumTracker.resetParameters(); andrew@9: outputFile.close(); andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/beatError" ){ andrew@10: newBeatInformation(m);//this is the main beat error routine (input) andrew@4: }//end if new error andrew@2: andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/tatum" ){ andrew@2: drumTracker.beatTimes.tatum = m.getArgAsFloat(0); andrew@2: printf("got tatum as %f\n", m.getArgAsFloat(0)); andrew@2: } andrew@2: andrew@2: if ( m.getAddress() == "/startTatum" ){ andrew@2: drumTracker.startTatum(m.getArgAsFloat(0)); andrew@2: printf("START TATUM %f\n", m.getArgAsFloat(0)); andrew@2: //then change so tempo distribution is correct.... andrew@2: }//end start tatum andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/uniformTempo" ){ andrew@2: drumTracker.setUniformTempo(); andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/uniformPhase" ){ andrew@2: drumTracker.setUniformPhase(); andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/setBeatNow" ){ andrew@2: andrew@2: double beatTime = m.getArgAsFloat(0); andrew@2: drumTracker.setBeatNow(beatTime); andrew@2: //printf("SET BEAT NOW %f\n", beatTime); andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/clickindex" ){ andrew@2: andrew@2: int clickIndex = m.getArgAsInt32(0); andrew@2: float clickTime = m.getArgAsFloat(1); andrew@2: drumTracker.setNewClickIndex(clickIndex, clickTime); andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/newBeat" ){ andrew@2: int beatIndex = m.getArgAsInt32(0); andrew@2: drumTracker.newBeat(beatIndex); andrew@2: } andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/beatCorrection" ) andrew@2: { andrew@2: float beatCorrValue = m.getArgAsFloat(0); andrew@2: drumTracker.doBeatCorrection(beatCorrValue); andrew@2: andrew@2: }//end correction by andrew@2: andrew@2: andrew@2: if ( m.getAddress() == "/BayesianNoise" ){ andrew@2: drumTracker.beatDistribution.likelihoodNoise = m.getArgAsFloat(0);; andrew@2: printf("bayesian noise set to %f\n", drumTracker.beatDistribution.likelihoodNoise); andrew@2: // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev); andrew@2: } andrew@2: andrew@2: if ( m.getAddress() == "/BayesianStdDev" ){ andrew@10: drumTracker.beatDistribution.likelihoodStdDev = drumTracker.arraySize / m.getArgAsFloat(0); andrew@2: // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev); andrew@2: } andrew@2: andrew@2: andrew@2: }//end while there is new message andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@10: void testApp::newBeatInformation(const ofxOscMessage& m){ andrew@10: andrew@10: double timeNow = ofGetElapsedTimeMillis(); andrew@10: // if (timeNow - drumTracker.setBeatToNowTime > 1000) andrew@10: andrew@10: int beatTime = round(m.getArgAsFloat(2)); andrew@10: recentError = m.getArgAsFloat(0); andrew@10: int size = drumTracker.beatDistribution.arraySize; andrew@10: int newIndex = round((size/2)+(recentError*size)); andrew@10: priorValue = drumTracker.beatDistribution.posterior[newIndex]; andrew@11: andrew@10: drumTracker.newKickError(m.getArgAsFloat(0), m.getArgAsFloat(2), m.getArgAsString(1)); andrew@10: andrew@10: KLdiv = drumTracker.beatDistribution.getKLdivergence(); andrew@10: entropy = drumTracker.beatDistribution.getEntropyOfPosterior(); andrew@11: priorEntropy = drumTracker.beatDistribution.getEntropyOfPrior(); andrew@10: andrew@10: drumType = m.getArgAsString(1); andrew@10: int drumIndicator = 2; andrew@10: if (drumType == "kick") andrew@10: drumIndicator = 1; andrew@10: andrew@10: andrew@10: beatPosition = m.getArgAsFloat(3); andrew@10: printf("NEW BEAT: time %f error %f, position %f, drum %s, ", beatTime, recentError, beatPosition, drumType.c_str()); andrew@10: andrew@11: printf("KL div %f, entropy %f prior Entropy %f prior value %f, ", KLdiv, entropy, priorEntropy, priorValue); andrew@10: andrew@10: printf("tatum is %f\n", drumTracker.beatTimes.tatum ); andrew@10: andrew@10: andrew@10: if (outputFile.is_open()){ andrew@10: outputFile.precision(4); andrew@11: outputFile << fixed << beatTime << ", " << drumIndicator << ", " << recentError << ", " << beatPosition << ", " ; andrew@10: outputFile.precision(6); andrew@11: outputFile << fixed << priorValue << ", " << KLdiv << ", " << entropy << ", " << priorEntropy << ", " << drumTracker.beatTimes.tatum << "\n"; andrew@10: }else{ andrew@10: printf("file not open\n"); andrew@10: } andrew@10: andrew@10: andrew@10: } andrew@10: andrew@10: andrew@2: void testApp::takePictureOfScreen(){ andrew@2: // grab a rectangle at 200,200, width and height of 300,180 andrew@2: img.grabScreen(0,0,screenWidth,screenHeight); andrew@2: char fileName[255]; andrew@10: sprintf(fileName, "snapshot_%.3i.png", snapCounter); andrew@2: img.saveImage(fileName); andrew@2: //printf("saved %s\n", fileName); andrew@2: snapCounter++; andrew@2: bSnapshot = false; andrew@2: } andrew@2: andrew@2: /* andrew@2: void testApp::setBeatDistribution(int beatPosition){ andrew@2: switch (beatPosition){ andrew@2: //early sixteenth is that the beat is a sixteenth earlier andrew@2: case 0: andrew@2: case 1: andrew@2: case 11: andrew@2: //i.e. these zones are interpreted as "on the beat" andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0; andrew@2: beatDistribution.lateSixteenthNoteProportion = 0; andrew@2: break; andrew@2: //10 and 2 were here andrew@2: andrew@2: case 2: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8 andrew@2: //i.e. a 25% chance it is early sixteenth - 75% that the beat actually lies here andrew@2: beatDistribution.lateSixteenthNoteProportion = 0; andrew@2: break; andrew@2: andrew@2: case 3: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0.3;//was 0.4 in Bayesian8 //half chance it is early andrew@2: beatDistribution.lateSixteenthNoteProportion = 0; andrew@2: break; andrew@2: andrew@2: case 5: andrew@2: case 6: andrew@2: case 7: andrew@2: beatDistribution.eighthNoteProportion = 0.3;//i.e. nearly half a chance we are on the 8th note andrew@2: beatDistribution.earlySixteenthNoteProportion = 0; andrew@2: beatDistribution.lateSixteenthNoteProportion = 0; andrew@2: break; andrew@2: andrew@2: case 4: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8 andrew@2: beatDistribution.lateSixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8 andrew@2: //chsanged to 0.2 and 0.1 then back andrew@2: break; andrew@2: andrew@2: case 8: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8 andrew@2: beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8 andrew@2: break; andrew@2: andrew@2: case 9: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0; andrew@2: beatDistribution.lateSixteenthNoteProportion = 0.35;//was 0.4 in Bayesian8 andrew@2: break; andrew@2: andrew@2: case 10: andrew@2: beatDistribution.eighthNoteProportion = 0; andrew@2: beatDistribution.earlySixteenthNoteProportion = 0; andrew@2: beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.2 in Bayesian8 andrew@2: break; andrew@2: andrew@2: } andrew@2: andrew@2: } andrew@2: */ andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::draw(){ andrew@2: //--------------------------- lines andrew@2: // a bunch of red lines, make them smooth if the flag is set andrew@2: andrew@2: andrew@2: andrew@2: if (bSmooth){ andrew@2: ofEnableSmoothing(); andrew@2: } andrew@2: andrew@2: switch (screenToDraw){ andrew@2: case 0: andrew@2: drawBayesianDistribution(); andrew@2: break; andrew@2: case 1: andrew@2: drawTempoDistribution(); andrew@2: break; andrew@2: case 2: andrew@2: drawBeatMap(); andrew@2: break; andrew@2: case 3: andrew@2: // drawNormalisedLikelihood(); andrew@2: drawRestrictedTempoDistribution(tempoWindowMinimum, tempoWindowMaximum); andrew@2: break; andrew@2: case 4: andrew@2: drawTempoData(); andrew@2: break; andrew@2: case 5: andrew@2: drawBeatProbabilityDistribution(); andrew@2: break; andrew@2: case 6: andrew@2: drawPosterior(); andrew@2: break; andrew@2: case 7: andrew@2: drawGreyscaleBayesianDistribution(); andrew@2: break; andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: if (bSnapshot == true){ andrew@2: takePictureOfScreen(); andrew@2: bSnapshot = false; andrew@2: } andrew@2: andrew@3: andrew@3: andrew@3: drawKLdivAndEntropy(); andrew@3: andrew@3: }//end draw andrew@3: andrew@3: andrew@3: void testApp::drawKLdivAndEntropy(){ andrew@2: ofDrawBitmapString("KLdiv :"+ofToString(KLdiv, 3), 20, 40); andrew@2: ofSetColor(200,0,0,160); andrew@2: ofRect(0, ofGetHeight()*(1-KLdiv), 40, ofGetHeight()*KLdiv); andrew@2: andrew@3: ofSetColor(0,0, 200, 160); andrew@3: ofDrawBitmapString("Entropy :"+ofToString(entropy, 3), 20, 60); andrew@3: double entropyDrawFactor = 0.1; andrew@3: ofRect(60, ofGetHeight()*(1-entropy*entropyDrawFactor), 40, ofGetHeight()*entropy*entropyDrawFactor); andrew@4: andrew@4: ofSetColor(100,0,200, 220); andrew@4: ofDrawBitmapString("Error :"+ofToString(recentError, 3), 20, 80); andrew@4: ofRect(120, ofGetHeight()*(1-fabs(recentError)), 40, ofGetHeight()*2*fabs(recentError)); andrew@4: andrew@8: ofDrawBitmapString("prior val :"+ofToString(priorValue, 3), 20, 100); andrew@8: andrew@8: andrew@8: andrew@4: ofSetColor(100,0,100, 220); andrew@4: ofDrawBitmapString(drumType, 20, 0); andrew@4: andrew@3: } andrew@2: andrew@2: andrew@2: void testApp::drawTempoData(){ andrew@2: andrew@2: ofSetColor(0xFFFF00); andrew@2: //yellow line in centre andrew@2: ofLine( 0, (screenHeight/2), screenWidth, (screenHeight/2)); andrew@2: andrew@2: ofSetColor(0x0000FF); andrew@2: int tempoIndex = 0; andrew@2: int widthOffset = 20; andrew@2: float stepWidth = screenWidth / 16; andrew@2: ofDrawBitmapString("tatums : ", 600,180); andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.tatum, 1), 700,180); andrew@2: ofDrawBitmapString("bpm : ", 600,200); andrew@2: ofDrawBitmapString(ofToString((drumTracker.beatTimes.tatum/30000), 1), 700,200); andrew@2: int intervalIndex; andrew@2: int intervalWidth = 2; andrew@2: float magnifyingFactor = 8; andrew@2: for (tempoIndex = 0;tempoIndex < 16; tempoIndex++){ andrew@2: andrew@2: for (intervalIndex = 0;intervalIndex < 16;intervalIndex++){ andrew@2: //new color code andrew@2: if (drumTracker.beatTimes.intervalUsed[tempoIndex][intervalIndex] == true){ andrew@2: ofSetColor(0x00FFFF); andrew@2: } andrew@2: else{ andrew@2: ofSetColor(0xFF00FF); andrew@2: } andrew@2: //end new code andrew@2: andrew@2: ofLine((stepWidth*tempoIndex)+ (intervalWidth*intervalIndex) + widthOffset, screenHeight, andrew@2: (stepWidth*tempoIndex) + (intervalWidth*intervalIndex) + widthOffset, (screenHeight/2) * (1 + (magnifyingFactor * (1-drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex])))); andrew@2: andrew@2: if (printInterval == true){ andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex], 3), andrew@2: (stepWidth*tempoIndex) + widthOffset,20+(intervalIndex*20)); andrew@2: } andrew@2: andrew@2: andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][0], 3), 700,220+(tempoIndex*20)); andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][1], 1), 750,220+(tempoIndex*20)); andrew@2: }//end for interval index andrew@2: }//end for tempo index andrew@2: andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.clickIndex), 750,20); andrew@2: andrew@2: ofDrawBitmapString(ofToString(mouseBPM), 50,20); andrew@2: ofDrawBitmapString(drumTracker.tempoDataString, 50, 100); andrew@2: andrew@2: }//end draw tempo data andrew@2: andrew@2: andrew@2: void testApp::drawTempoDistribution(){ andrew@10: float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize)); andrew@2: andrew@2: maximum *= 1.1; andrew@2: andrew@2: float stepHeight = screenHeight/maximum; andrew@2: andrew@2: andrew@2: andrew@2: //draw prior in green andrew@2: ofSetColor(0x888888); andrew@10: for (int i = 1; i < drumTracker.arraySize; i+=2){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //draw posterior in dark andrew@2: ofSetColor(0x000000); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //black line is the max probability andrew@2: ofSetColor(0x000000); andrew@2: ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0); andrew@2: andrew@2: //blue is the current kick received andrew@2: ofSetColor(0xAAAAAA); andrew@2: andrew@2: int altIndex = 0; andrew@2: for (altIndex = 0;altIndex< 16;altIndex++){ andrew@2: andrew@2: double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex]; andrew@2: andrew@2: if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){ andrew@2: andrew@2: andrew@2: andrew@2: //draw likelihood andrew@2: //draw likelhood in blue andrew@2: // //need to reset likelihood for this! andrew@2: //XXX remove andrew@2: double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex]; andrew@2: if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum) andrew@2: { andrew@2: andrew@10: ofLine(stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), screenHeight, andrew@10: stepSize*(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 0); andrew@2: andrew@10: drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight)); andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: }//end for andrew@2: andrew@2: if (bSmooth){ andrew@2: ofDisableSmoothing(); andrew@2: } andrew@2: andrew@2: drawTempoInfo(); andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: int testApp::xcoordinateFromTempoDataPoint(float f){ andrew@2: //f is the time andrew@2: andrew@2: int xcoordinateForInterval = 0; andrew@2: if (f >= drumTracker.tempoMinimum && f <= drumTracker.tempoMaximum) andrew@2: xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum)*screenWidth/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum)); andrew@2: return xcoordinateForInterval; andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: int testApp::xcoordinateFromRestrictedTempoDataPoint(float f, const int& tmpMin, const int& tmpMax){ andrew@2: andrew@2: andrew@2: int xcoordinateForInterval = -1; andrew@2: if (f >= drumTracker.tempoMinimum+tmpMin && f <= min(drumTracker.tempoMinimum+tmpMax,drumTracker.tempoMaximum)) andrew@2: xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum - tmpMin*arrayToMsecScaleFactor)*screenWidth/(float)((tmpMax - tmpMin)*arrayToMsecScaleFactor)); andrew@2: return xcoordinateForInterval; andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::drawTempoInfo(){ andrew@10: float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize)); andrew@2: andrew@2: andrew@2: ofSetColor(0x000000); andrew@2: string testString; andrew@2: testString = "max is "; andrew@2: testString += ofToString(maximum); andrew@2: ofDrawBitmapString(testString, 700,620); andrew@2: andrew@2: ofDrawBitmapString(msg_string, 700,650); andrew@2: andrew@2: ofDrawBitmapString(kickString, 700,670); andrew@2: andrew@2: testString = "std dev : "; andrew@2: testString += ofToString(drumTracker.tempoStdDev, 6); andrew@2: andrew@2: testString += ", "; andrew@2: testString += ofToString(drumTracker.accompanimentStarted); andrew@2: ofDrawBitmapString(testString, 20, 120); andrew@2: andrew@2: int tempoUpdateIndex; andrew@2: for (tempoUpdateIndex = 0;tempoUpdateIndex<16;tempoUpdateIndex++){ andrew@2: // ofDrawBitmapString(tempoUpdateStrings[tempoUpdateIndex], 700, 200 + (20 * tempoUpdateIndex)); andrew@2: } andrew@2: andrew@2: ofDrawBitmapString("Mouse located at tempo: ", 50,10); andrew@2: ofDrawBitmapString(ofToString(mouseBPM, 1), 50,20); andrew@2: andrew@2: ofDrawBitmapString("Current tempo: ", 50,40); andrew@2: ofDrawBitmapString(ofToString(30000/drumTracker.beatTimes.tatum, 1), 50,50); andrew@2: andrew@2: ofDrawBitmapString(drumTracker.tempoDataString, 50, 100); andrew@2: andrew@2: andrew@2: for (int i = 1;i < 16; i++){ andrew@2: for (int altIndex = 0; altIndex < 16;altIndex++){ andrew@2: string newString; andrew@2: newString = " :"; andrew@2: int recentIndex = (altIndex-i+16)%16; andrew@2: if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){ andrew@2: andrew@2: andrew@2: int xcoordinateForInterval = xcoordinateFromTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex]); andrew@2: float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2; andrew@2: andrew@2: if (drumTracker.beatTimes.OnsetIsKick[altIndex]) andrew@2: ofSetColor(255*(8-beatInterval)/(float)8, 0, 255*beatInterval/(float)8); andrew@2: else andrew@2: ofSetColor(0, 255*(8-beatInterval)/(float)8, 255*beatInterval/(float)8); andrew@2: //red kick, green snare andrew@2: andrew@2: ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3); andrew@2: andrew@2: newString += ofToString(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex],0); andrew@2: newString += " ("; andrew@2: newString += ofToString(drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0); andrew@2: newString += ")"; andrew@2: andrew@2: } andrew@2: ofSetColor(0,0,0); andrew@2: //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20)); andrew@2: andrew@2: andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawTempoDataPoints(const int& tmpMin, const int& tmpMax, const float& tmpStepSize){ andrew@2: andrew@2: for (int i = 1;i < 16; i++){ andrew@2: for (int altIndex = 0; altIndex < 16;altIndex++){ andrew@2: // string newString; andrew@2: // newString = " :"; andrew@2: andrew@2: int recentIndex = (altIndex-i+16)%16; andrew@2: if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){ andrew@2: andrew@2: int xcoordinateForInterval = xcoordinateFromRestrictedTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex], tmpMin, tmpMax); andrew@2: float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2; andrew@2: andrew@2: if (drumTracker.beatTimes.OnsetIsKick[altIndex]) andrew@2: ofSetColor(255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7, 0);//100+155*(8-beatInterval)/(float)8 andrew@2: else andrew@2: ofSetColor(0, 255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7);//, 155*beatInterval/(float)8); andrew@2: //red kick, green snare andrew@2: andrew@2: ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3); andrew@2: ofDrawBitmapString(ofToString(beatInterval, 0), xcoordinateForInterval-2, 200 + (altIndex * 20) - 3); andrew@2: /* newString += ofToString(beatTimes.intervalDifferences[altIndex][recentIndex],0); andrew@2: newString += " ("; andrew@2: newString += ofToString(beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0); andrew@2: newString += ")"; andrew@2: */ andrew@2: } andrew@2: ofSetColor(0,0,0); andrew@2: //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20)); andrew@2: andrew@2: andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::drawRestrictedTempoDistribution(int tmpMin, int tmpMax){ andrew@2: //min and max are in the tempo array coordinates andrew@2: andrew@2: tmpMin = max(tmpMin, 0); andrew@10: tmpMax = min(tmpMax, drumTracker.arraySize-1); andrew@2: andrew@10: float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize)); andrew@2: andrew@2: maximum *= 1.1; andrew@2: andrew@2: float stepHeight = screenHeight/maximum; andrew@2: int tmpWidth = tmpMax - 1 - tmpMin; andrew@2: float tmpStepSize = screenWidth / (float) tmpWidth; andrew@2: andrew@2: andrew@2: //draw prior in green andrew@2: ofSetColor(0x888888); andrew@2: for (int i = 1; i < tmpWidth; i+=2){ andrew@2: ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i-1]*stepHeight), i * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //draw posterior in dark andrew@2: ofSetColor(0x000000); andrew@2: for (int i = 1; i < tmpWidth; i++){ andrew@2: ofLine((i-1) * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //black line is the max probability andrew@2: ofSetColor(0x000000); andrew@2: ofLine((drumTracker.tempoDistribution.integratedEstimate - tmpMin)* tmpStepSize, screenHeight, (drumTracker.tempoDistribution.integratedEstimate-tmpMin) *tmpStepSize, 0); andrew@2: andrew@2: //blue is the current kick received andrew@2: ofSetColor(0xAAAAAA); andrew@2: andrew@2: int altIndex = 0; andrew@2: for (altIndex = 0;altIndex< 16;altIndex++){ andrew@2: //iterate through all recent beat intervals andrew@2: andrew@2: double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex]; andrew@2: andrew@2: if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){ andrew@2: andrew@2: double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex]; andrew@2: andrew@2: if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum){ andrew@2: //i.e. within the beat range only andrew@2: //so we only draw the likelihood realtime for happening beat intervals andrew@2: //in fact much more is going on than this but harder to visualise andrew@2: andrew@10: float indexOfNewLocation = drumTracker.arraySize*(tempoInterval-drumTracker.tempoMinimum)/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum); andrew@2: andrew@2: andrew@2: if (indexOfNewLocation >= tmpMin){ andrew@2: ofLine(tmpStepSize * (indexOfNewLocation-tmpMin), screenHeight, tmpStepSize * (indexOfNewLocation-tmpMin) , 0); andrew@2: } andrew@2: andrew@2: andrew@10: drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev); andrew@2: //setting the tempo distribution likeihood just for visualisation purposes andrew@2: for (int i = 1; i < tmpWidth; i++){ andrew@2: ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin]*stepHeight)); andrew@2: andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: }//end for andrew@2: andrew@2: if (bSmooth){ andrew@2: ofDisableSmoothing(); andrew@2: } andrew@2: andrew@2: andrew@2: drawTempoDataPoints(tmpMin, tmpMax, tmpStepSize); andrew@2: andrew@2: // lines for background andrew@2: for (int i = tmpMin-(tmpMin%20);i < tmpMax; i+=20){ andrew@2: ofSetColor(0,0,200,100); andrew@2: ofLine(tmpStepSize * (i-tmpMin), screenHeight, tmpStepSize * (i-tmpMin) , 0); andrew@2: string tmpTempoString = ofToString(drumTracker.tempoMinimum + i*arrayToMsecScaleFactor, 0); andrew@2: ofDrawBitmapString(tmpTempoString, tmpStepSize * (i-tmpMin) , 20); andrew@2: } andrew@2: andrew@2: string currentTatumString = "Beat Period : "; andrew@2: currentTatumString += ofToString(drumTracker.beatTimes.tatum, 1); andrew@2: currentTatumString += " MaxIndex : "; andrew@2: currentTatumString += ofToString(drumTracker.tempoDistribution.integratedEstimate, 1); andrew@2: andrew@2: ofDrawBitmapString(currentTatumString, 20, 40); andrew@2: //drawTempoInfo(); andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawBeatMap(){ andrew@2: int x,y; andrew@2: andrew@2: for (x=0;x < 6;x++){ andrew@2: for (y=0;y<8;y++){ andrew@2: int cell = x+(y*6); andrew@2: if (cell == drumTracker.beatTimes.beatSegment){ andrew@2: if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick andrew@2: ofSetColor(drumTracker.beatTimes.beatMap[cell]*255, 0, 0); andrew@2: andrew@2: if (drumTracker.beatTimes.beatMap[cell] == 2)//for kick andrew@2: ofSetColor(0, drumTracker.beatTimes.beatMap[cell]*255, 100); andrew@2: andrew@2: } andrew@2: else{ andrew@2: if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick andrew@2: ofSetColor(drumTracker.beatTimes.beatMap[cell]*155, 0, 0); andrew@2: else //for snare andrew@2: ofSetColor(0,drumTracker.beatTimes.beatMap[cell]*155, 0);//beatTimes.beatMap[cell]*155); andrew@2: andrew@2: } andrew@2: ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8); andrew@2: andrew@2: ofSetColor(255,0,0); andrew@2: ofDrawBitmapString(ofToString(x+(y*6)), screenWidth*x/6, screenHeight*y/8); andrew@2: andrew@2: if (drumTracker.beatTimes.beatMap[cell] == 1){ andrew@2: ofSetColor(0,255,255);// andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) ); andrew@2: } andrew@2: if (drumTracker.beatTimes.beatMap[cell] == 2){ andrew@2: ofSetColor(0,0,100);// andrew@2: ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) ); andrew@2: } andrew@2: andrew@2: andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawBeatProbabilityDistribution(){ andrew@2: int x,y; andrew@2: andrew@2: for (x=0;x < 6;x++){ andrew@2: for (y=0;y<4;y++){ andrew@2: int cell = x+(y*6); andrew@2: ofSetColor(drumTracker.beatTimes.beatProbabilityDistribution[y][x][0]*255, 0, 0); andrew@2: ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8); andrew@2: } andrew@2: } andrew@2: for (x=0;x < 6;x++){ andrew@2: for (y=0;y<4;y++){ andrew@2: int cell = x+(y*6); andrew@2: ofSetColor(0, drumTracker.beatTimes.beatProbabilityDistribution[y][x][1]*255, 0); andrew@2: ofRect(screenWidth*x/6, screenHeight*(y+4)/8, screenWidth/6, screenHeight/8); andrew@2: } andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::drawNormalisedLikelihood(){ andrew@10: float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize)); andrew@10: //maximum = max(maximum, beatDistribution.getMaximum(&beatDistribution.posterior[0], drumTracker.arraySize)); andrew@2: float stepHeight = screenHeight/maximum; andrew@2: andrew@2: if (!hidePriorMode){ andrew@2: //draw likelhood in blue andrew@2: andrew@2: ofSetColor(0x0000FF); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: //draw prior in green andrew@2: ofSetColor(0x00AA00); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight)); andrew@2: } andrew@2: }//end hide prior mode andrew@2: andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawPosterior(){ andrew@10: float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize); andrew@2: andrew@2: if (drumTracker.posteriorMaximum < maximum){ andrew@2: drumTracker.posteriorMaximum = 1.2*maximum; andrew@2: } andrew@2: andrew@2: float stepHeight = screenHeight/drumTracker.posteriorMaximum; andrew@2: ofSetColor(0xFF00FF); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //yellow is the middle andrew@2: ofSetColor(0xFFFF00); andrew@10: ofLine(drumTracker.arraySize*stepSize/2, screenHeight, drumTracker.arraySize*stepSize/2, 0); andrew@2: andrew@2: andrew@2: andrew@2: //blue is the current kick received andrew@2: ofSetColor(0x0000FF); andrew@10: ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), screenHeight,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), 0); andrew@2: andrew@2: //purple line is the integrated max probability andrew@2: int integratedBeatEstimateDrawPoint = round(drumTracker.beatDistribution.integratedEstimate*stepSize) ; andrew@2: ofSetColor(0xFF22FF); andrew@2: ofLine(integratedBeatEstimateDrawPoint, screenHeight, integratedBeatEstimateDrawPoint, 0); andrew@2: andrew@2: string testString = "maximum: "; andrew@2: testString += ofToString(drumTracker.posteriorMaximum, 2); andrew@2: ofDrawBitmapString(testString, 100,120); andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawBayesianDistribution(){ andrew@10: float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize)); andrew@2: float stepHeight = screenHeight/maximum; andrew@2: andrew@2: if (!hidePriorMode){ andrew@2: //draw likelhood in blue andrew@2: if (drumTracker.onsetType == "kick") andrew@2: ofSetColor(0xff0000);//red : kick andrew@2: else andrew@2: ofSetColor(0x00FF00);//green : snare andrew@2: andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: //;line where the current kick is received andrew@10: ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), screenHeight,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), 0); andrew@2: andrew@2: andrew@2: //draw prior in aqua blue andrew@2: ofSetColor(0x00AAAA); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight)); andrew@2: } andrew@2: }//end hide prior mode andrew@2: andrew@2: //draw posterior in red andrew@2: ofSetColor(0x0000FF); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: //draw the previous updated posteriror in purple andrew@2: /* ofSetColor(0xFF22FF); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (tmpArray[i-1]*stepHeight), i*stepSize, screenHeight - (tmpArray[i]*stepHeight)); andrew@2: } andrew@2: */ andrew@2: andrew@2: //yellow is the middle andrew@2: ofSetColor(0xFFFF00); andrew@10: ofLine(drumTracker.arraySize*stepSize/2, screenHeight, drumTracker.arraySize*stepSize/2, 0); andrew@2: andrew@2: //black line is the max probability andrew@2: ofSetColor(0x000000); andrew@2: ofLine(drumTracker.beatDistribution.maximumIndex*stepSize, screenHeight, drumTracker.beatDistribution.maximumIndex*stepSize, 0); andrew@2: andrew@2: andrew@2: //purple line is the integrated max probability andrew@2: int integratedBeatEstimate = drumTracker.beatDistribution.integratedEstimate ; andrew@2: ofSetColor(0x2222FF); andrew@2: ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0); andrew@2: andrew@2: andrew@2: if (bSmooth){ andrew@2: ofDisableSmoothing(); andrew@2: } andrew@2: andrew@2: printBayesianData(); andrew@2: } andrew@2: andrew@2: void testApp::printBayesianData(){ andrew@2: //not optimised!!! XXX andrew@10: float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize)); andrew@2: andrew@2: ofSetColor(0x000000); andrew@2: string testString; andrew@2: testString = "max2 is "; andrew@2: testString += ofToString(maximum, 3); andrew@2: testString += " :: "; andrew@2: andrew@2: testString = "correction of "; andrew@2: testString += ofToString(drumTracker.beatCorrection); andrew@2: testString += " corr by :"; andrew@2: testString += ofToString(drumTracker.correctBeatBy); andrew@2: andrew@2: //ofDrawBitmapString(testString, 100,120); andrew@2: andrew@2: testString = "MaxPhase "; andrew@2: testString += ofToString(drumTracker.maxPhase); andrew@2: // ofDrawBitmapString(testString, 100,140); andrew@2: andrew@2: andrew@2: testString = "Likelihood noise "; andrew@2: testString += ofToString(drumTracker.beatDistribution.likelihoodNoise, 2); andrew@2: //ofDrawBitmapString(testString, 100,160); andrew@2: andrew@2: // ofDrawBitmapString(msg_string, 100,140); andrew@2: andrew@2: // ofDrawBitmapString(kickString, 100,180); andrew@2: andrew@2: /* debugString = "Min Debug = "; andrew@2: debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.minTempoIndex); andrew@2: debugString += " Max Debug = "; andrew@2: debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.maxTempoIndex); andrew@2: */ andrew@2: //ofDrawBitmapString(debugString, 300,370); andrew@2: andrew@2: debugString = "CLICK INDEX = "; andrew@2: debugString += ofToString(drumTracker.beatTimes.clickIndex); andrew@2: //ofDrawBitmapString(debugString, 100, 20); andrew@2: andrew@2: debugString = "STD DEV = "; andrew@2: debugString += ofToString(drumTracker.beatDistribution.standardDeviation, 2); andrew@2: // ofDrawBitmapString(debugString, 100, 40); andrew@2: andrew@2: andrew@2: andrew@2: debugString = "interval "; andrew@2: debugString += ofToString(drumTracker.debugArray[2], 2); andrew@2: debugString += " time int = "; andrew@2: debugString += ofToString(drumTracker.debugArray[1], 2); andrew@2: debugString += " Beat max = "; andrew@2: debugString += ofToString(drumTracker.debugArray[0 ], 2); andrew@2: debugString += " Tempo max = "; andrew@2: debugString += ofToString(drumTracker.debugArray[3 ], 2); andrew@2: // ofDrawBitmapString(debugString, 300,570); andrew@2: andrew@2: debugString = " last = "; andrew@2: debugString += ofToString(drumTracker.beatTimes.lastBeatTime, 2); andrew@2: // ofDrawBitmapString(debugString, 300,470); andrew@2: andrew@2: andrew@2: string closestClickString = "Closest Click "; andrew@2: closestClickString += ofToString(drumTracker.beatTimes.closestClickIndexToBeat[drumTracker.beatTimes.index]); andrew@2: closestClickString += " beat seg "; andrew@2: closestClickString += ofToString(drumTracker.beatTimes.beatSegment%12); andrew@2: closestClickString += " lastCindex"; andrew@2: closestClickString += ofToString(drumTracker.beatTimes.lastClickIndex); andrew@2: closestClickString += " TD "; andrew@2: closestClickString += ofToString(drumTracker.beatTimes.timeDifference); andrew@2: andrew@2: // ofDrawBitmapString(closestClickString, 100,100); andrew@2: andrew@2: // ofDrawBitmapString(timeString, 100,60); andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawGreyscaleBayesianDistribution(){ andrew@2: ofSetColor(255,255,255); andrew@2: ofRect(0,0,screenWidth, screenHeight); andrew@2: andrew@10: float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], drumTracker.arraySize)); andrew@2: maximum *= 1.1; andrew@2: float stepHeight = screenHeight/maximum; andrew@2: andrew@2: if (!hidePriorMode){ andrew@2: //draw likelhood in blue andrew@2: ofSetColor(0x555555); andrew@10: for (int i = 1; i < drumTracker.arraySize; i+=2){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: //draw prior in green andrew@2: ofSetColor(0xAAAAAA); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight)); andrew@2: } andrew@2: }//end hide prior mode andrew@2: andrew@2: //draw posterior in dark grey andrew@2: ofSetColor(0x222222); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: /* andrew@2: //dotted the middle andrew@2: ofSetColor(0x555555); andrew@2: for (int i = 1; i < screenHeight; i+=4){ andrew@10: ofLine(drumTracker.arraySize*stepSize/2, i, drumTracker.arraySize*stepSize/2, i-2); andrew@2: } andrew@2: */ andrew@2: andrew@2: //purple line is the integrated max probability andrew@2: // int integratedBeatEstimate = beatDistribution.integratedEstimate ; andrew@2: // ofSetColor(0x000000); andrew@2: // ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0); andrew@2: andrew@2: //purple line is the integrated max probability andrew@2: float tmpIntegratedBeatEstimate = drumTracker.beatDistribution.getIntegratedEstimateIndex(); andrew@2: ofSetColor(0x000000); andrew@2: int drawLinePoint = round(tmpIntegratedBeatEstimate *stepSize); andrew@2: ofLine(drawLinePoint, screenHeight, drawLinePoint, 0); andrew@2: andrew@2: //blue is the current kick received andrew@2: ofSetColor(0x555555); andrew@2: for (int i = 1; i < screenHeight; i+=40){ andrew@10: ofLine(stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), i,stepSize*((drumTracker.arraySize/2) + (drumTracker.arraySize*drumTracker.kickError)), i-20); andrew@2: } andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: void testApp::drawGreyscaleTempoDistribution(double tempoInterval){ andrew@2: ofSetColor(255,255,255); andrew@2: ofRect(0,0,screenWidth, screenHeight); andrew@2: andrew@10: float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], drumTracker.arraySize); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], drumTracker.arraySize)); andrew@10: maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], drumTracker.arraySize)); andrew@2: andrew@2: maximum *= 1.1; andrew@2: andrew@2: float stepHeight = screenHeight/maximum; andrew@2: andrew@2: //draw prior in green andrew@2: ofSetColor(0x777777); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //draw posterior in dark andrew@2: ofSetColor(0x000000); andrew@10: for (int i = 1; i < drumTracker.arraySize; i++){ andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: //black line is the max probability andrew@2: ofSetColor(0xFF0000); andrew@2: ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0); andrew@2: andrew@2: //blue is the current kick received andrew@2: ofSetColor(0xAAAAAA); andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: for (int k =1;k < screenHeight/12;k+=2){ andrew@10: ofLine(stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), 12*k, andrew@10: stepSize*(drumTracker.arraySize * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 12*(k-1)); andrew@2: } andrew@2: andrew@10: drumTracker.tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev); andrew@10: for (int i = 1; i < drumTracker.arraySize; i+=2){ andrew@2: //dotted line likelihood fn andrew@2: ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight)); andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: if (bSmooth){ andrew@2: ofDisableSmoothing(); andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::keyPressed (int key){ andrew@2: if (key == 's'){ andrew@2: bSmooth = !bSmooth; andrew@2: } andrew@11: if (key == 'n'){ andrew@11: if (outputFile.is_open()){ andrew@11: outputFile.close(); andrew@11: } andrew@11: outputFile.open("../../../data/baydrumTest.txt"); andrew@11: andrew@11: } andrew@11: andrew@2: if (key == 'x'){ andrew@2: printInterval = !printInterval; andrew@2: } andrew@2: andrew@2: andrew@2: if (key == 'y'){ andrew@2: drawData = !drawData; andrew@2: } andrew@2: andrew@2: if (key == 'f'){ andrew@2: ofToggleFullscreen(); andrew@2: } andrew@2: andrew@2: if (key == 'h' || key == 'H'){ andrew@2: hidePriorMode = !hidePriorMode;//drawData; andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: if ( key =='a' || key == 'A' ) andrew@2: { andrew@2: andrew@2: } andrew@2: andrew@2: if (key == ' '){ andrew@2: drumTracker.paused = !drumTracker.paused; andrew@2: } andrew@2: andrew@2: if (key == OF_KEY_RIGHT){ andrew@2: screenToDraw++; andrew@2: screenToDraw = screenToDraw % NUMBER_OF_SCREENS; andrew@2: } andrew@2: if (key == OF_KEY_LEFT){ andrew@2: screenToDraw += NUMBER_OF_SCREENS - 1; andrew@2: screenToDraw = screenToDraw % NUMBER_OF_SCREENS; andrew@2: } andrew@2: andrew@2: if (key == ']') andrew@10: drumTracker.beatDistribution.translateDistribution(drumTracker.arraySize / 4); andrew@2: andrew@2: if (key == '[') andrew@10: drumTracker.beatDistribution.translateDistribution(-1*drumTracker.arraySize / 4); andrew@2: andrew@2: if (key == 'x'){ andrew@2: bSnapshot = true; andrew@2: } andrew@2: andrew@2: if (key == 'q') andrew@2: drumTracker.adaptiveStandardDeviationMode = !drumTracker.adaptiveStandardDeviationMode; andrew@2: andrew@2: } andrew@2: andrew@2: /* andrew@2: void testApp::sendMaxTempo(){ andrew@2: ofxOscMessage m; andrew@2: m.setAddress( "/tempo" ); andrew@2: andrew@10: //maxTempo = tempoDistribution.maximumIndex * (tempoMaximum - tempoMinimum) / drumTracker.arraySize; andrew@2: //would be introduced new in bayesian8 andrew@10: maxTempo = drumTracker.tempoDistribution.getIntegratedEstimateIndex() * (tempoMaximum - tempoMinimum) / drumTracker.arraySize; andrew@2: maxTempo += tempoMinimum; andrew@2: andrew@2: andrew@2: m.addFloatArg( maxTempo ); andrew@2: sender.sendMessage( m ); andrew@2: andrew@2: printf("max tempo %f\n", maxTempo); andrew@2: andrew@2: } andrew@2: andrew@2: void testApp::sendMaxPhase(){ andrew@2: andrew@2: andrew@10: // maxPhase = (beatDistribution.maximumIndex - (drumTracker.arraySize/2)) / drumTracker.arraySize; andrew@10: maxPhase = (drumTracker.beatDistribution.getIntegratedEstimateIndex() - (drumTracker.arraySize/2)) / drumTracker.arraySize; andrew@2: printf("\nphase index %f :: %i\n", drumTracker.beatDistribution.integratedEstimate , maxPhase); andrew@2: ofxOscMessage m; andrew@2: m.setAddress( "/phase" ); andrew@2: m.addFloatArg( maxPhase ); andrew@2: sender.sendMessage( m ); andrew@2: andrew@2: //beatCorrection = maxPhase * beatTimes.tatum / 4; andrew@2: } andrew@2: */ andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::keyReleased (int key){ andrew@2: andrew@2: } andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::mouseMoved(int x, int y ){ andrew@2: andrew@2: mouseBPM = convertToBPM(drumTracker.tempoMinimum+ ((x * (drumTracker.tempoMaximum - drumTracker.tempoMinimum) ) / ofGetWidth() )) ; andrew@2: } andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::mouseDragged(int x, int y, int button){ andrew@2: } andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::mousePressed(int x, int y, int button){ andrew@2: } andrew@2: andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::mouseReleased(int x, int y, int button){ andrew@2: andrew@2: } andrew@2: andrew@2: //-------------------------------------------------------------- andrew@2: void testApp::windowResized(int w, int h){ andrew@2: screenWidth = ofGetWidth(); andrew@2: screenHeight = ofGetHeight(); andrew@10: stepSize = screenWidth / (float)(drumTracker.arraySize); andrew@2: } andrew@2: andrew@2: double testApp::convertToBPM(double interval){ andrew@2: //interval is in ms and is the tatum interval - eighth nbote - so 250ms for 120bpm andrew@2: return (30000/interval); andrew@2: andrew@2: } andrew@2: /* andrew@2: noyt needed? andrew@2: float testApp::tempoIndexToMsec(int index){ andrew@2: float msec; andrew@10: msec = index * (tempoMaximum - tempoMinimum) / drumTracker.arraySize; andrew@2: msec += tempoMinimum; andrew@2: return msec; andrew@2: } andrew@2: andrew@2: float testApp::beatIndexToMsec(int index){ andrew@2: float msec; andrew@10: msec = index * maxTempo / drumTracker.arraySize; andrew@2: msec += tempoMinimum; andrew@2: return msec; andrew@2: } andrew@2: */ andrew@2: /* andrew@2: andrew@2: bool testApp::filterBeatTime(double newBeatTime){ andrew@2: bool newBeatFound = false; andrew@2: if ((newBeatTime - beatTimes.lastBeatTime) > 20 || beatTimes.lastBeatTime == 0){ andrew@2: andrew@2: crossUpdateArrays((float)(newBeatTime - beatTimes.lastBeatTime)); andrew@2: beatTimes.lastBeatTime = newBeatTime; andrew@2: newBeatFound = true; andrew@2: } andrew@2: return newBeatFound; andrew@2: } andrew@2: andrew@2: void testApp::crossUpdateArrays(float timeInterval){ andrew@2: andrew@2: int finalBeatIndex, tmpTempoIndex, startBeatIndex; andrew@2: //finalBeat has contribution from BEAT[finalBeat + INT.k] * TEMPO[Max_tempo + k] where INT = INTERVAL andrew@2: float interval; andrew@2: interval = timeInterval / maxTempo;//beatTimes.tatum; andrew@2: tempoDistribution.resetMaximumPosterior(); andrew@2: beatDistribution.resetMaximumPosterior(); andrew@2: andrew@2: andrew@2: int tmpBeatIndex; andrew@2: //&& interval > 0.8 idea? andrew@2: if (timeInterval > 0 && timeInterval < 12000 ){//need between 0 and 12 seconds only to update andrew@2: andrew@10: for (tmpBeatIndex = 0;tmpBeatIndex < drumTracker.arraySize;tmpBeatIndex++){ andrew@2: andrew@2: tmpArray[tmpBeatIndex] = 0; andrew@2: float minusMsecToMakeUp = beatIndexToMsec(tmpBeatIndex) / interval; andrew@10: float plusMsecToMakeUp = beatIndexToMsec(drumTracker.arraySize - tmpBeatIndex) / interval; andrew@10: float convertMsecToTempoIndex = drumTracker.arraySize / (tempoMaximum - tempoMinimum) ; andrew@2: andrew@2: andrew@2: int minTempoIndex = -1 * (int)(minusMsecToMakeUp * convertMsecToTempoIndex); andrew@2: int maxTempoIndex = (int)(plusMsecToMakeUp * convertMsecToTempoIndex); andrew@2: andrew@2: andrew@2: if (tmpBeatIndex == beatDistribution.maximumIndex){ andrew@2: minTmpDebug = tempoDistribution.maximumIndex + minTempoIndex; andrew@2: maxTmpDebug = tempoDistribution.maximumIndex + maxTempoIndex; andrew@2: debugArray[0] = beatDistribution.maximumIndex;// andrew@2: debugArray[1] = timeInterval; andrew@2: debugArray[2] = interval;//beatDistribution.maximumIndex; andrew@2: debugArray[3] = tempoDistribution.maximumIndex; andrew@2: } andrew@2: andrew@2: for (tmpTempoIndex = minTempoIndex;tmpTempoIndex <= maxTempoIndex;tmpTempoIndex++){ andrew@2: andrew@2: if ((tempoDistribution.maximumIndex + tmpTempoIndex) >= 0 andrew@10: && (tempoDistribution.maximumIndex + tmpTempoIndex) < drumTracker.arraySize andrew@2: && (tmpBeatIndex - (int)(interval*tmpTempoIndex)) >= 0 andrew@10: && (tmpBeatIndex - (int)(interval*tmpTempoIndex))< drumTracker.arraySize){ andrew@2: tmpArray[tmpBeatIndex] += beatDistribution.posterior[tmpBeatIndex - (int)(interval*tmpTempoIndex)] * tempoDistribution.posterior[(int)tempoDistribution.maximumIndex + tmpTempoIndex]; andrew@2: } andrew@2: }//end for tmpTmepo andrew@2: andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: float tmpFloat; andrew@10: for (tmpBeatIndex = 0;tmpBeatIndex < drumTracker.arraySize;tmpBeatIndex++){ andrew@2: //debug - dont actually update:: andrew@2: andrew@2: tmpFloat = beatDistribution.posterior[tmpBeatIndex]; andrew@2: beatDistribution.posterior[tmpBeatIndex] = tmpArray[tmpBeatIndex]; andrew@2: tmpArray[tmpBeatIndex] = tmpFloat; andrew@2: } andrew@10: beatDistribution.renormaliseArray(&beatDistribution.posterior[0], drumTracker.arraySize); andrew@2: andrew@2: } //end if andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void testApp::updateTempoProcess(double cpuTime, string onsetDescription){ andrew@2: andrew@2: if (filterBeatTime(cpuTime) == true){ andrew@2: //checks for no repeat andrew@2: andrew@2: if (onsetDescription == "kick") andrew@2: beatTimes.addBeatTime(cpuTime, 1); andrew@2: else andrew@2: beatTimes.addBeatTime(cpuTime, 2); andrew@2: andrew@2: andrew@2: //recalculate the distribution andrew@2: int altIndex = 0; andrew@2: andrew@2: tempoDataString = "Tatum :"; andrew@2: tempoDataString += ofToString(beatTimes.tatum, 2); andrew@2: tempoDataString += " BPM "; andrew@2: tempoDataString += ofToString((double)30000/beatTimes.tatum, 2); andrew@2: andrew@2: timeString = "Last BEAT "; andrew@2: timeString += ofToString(beatTimes.lastBeatTime); andrew@2: timeString += " CLICK "; andrew@2: timeString += ofToString(beatTimes.lastClickTime); andrew@2: timeString += " DIFDF "; andrew@2: timeString += ofToString(beatTimes.timeDifference); andrew@2: timeString += " segment "; andrew@2: timeString += ofToString(beatTimes.beatSegment); andrew@2: andrew@2: andrew@2: for (altIndex = 0;altIndex< 16;altIndex++){ andrew@2: tempoInterval = beatTimes.intervalDifferences[beatTimes.index][altIndex]; andrew@2: integerMultipleOfTatum = beatTimes.relativeIntervals[altIndex][1]; andrew@2: andrew@2: andrew@2: ///NEW VERSION andrew@2: tempoUpdateStrings[altIndex] = ""; andrew@2: double timeInterval = beatTimes.beatTimes[beatTimes.index] - beatTimes.beatTimes[altIndex]; andrew@2: //raw time difference andrew@2: beatTimes.intervalDifferences[beatTimes.index][altIndex] = 0; andrew@2: beatTimes.intervalUsed[beatTimes.index][altIndex] = false; andrew@2: andrew@2: if (onsetType == "kick") andrew@2: beatTimes.OnsetIsKick[beatTimes.index] = true; andrew@2: else andrew@2: beatTimes.OnsetIsKick[beatTimes.index] = false; andrew@2: andrew@2: andrew@2: andrew@2: if (!accompanimentStarted){ andrew@2: //if we need to find tempo and start use this method andrew@2: //we have 'started' once std dev is sufficiently low andrew@2: andrew@2: updateTempoIfWithinRange(timeInterval);//taken as being the tatum interval andrew@2: andrew@2: andrew@2: andrew@2: for (int i = 1;i <= 4;i++){ andrew@2: //we test the main beats and the two bar (16 tatum intervals) andrew@2: andrew@2: double testInterval = timeInterval / 2*i;//pow(2, i);//pow(2.0, i); andrew@2: andrew@2: if (updateTempoIfWithinRange(testInterval)){ andrew@2: printf("test time %f, beats %i\n", testInterval, i); andrew@2: andrew@2: beatTimes.intervalUsed[beatTimes.index][altIndex] = true; andrew@2: beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval; andrew@2: //xx what if two within range here? andrew@2: andrew@2: tempoUpdateStrings[altIndex] = "Tempo Updates ("; andrew@2: tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0); andrew@2: tempoUpdateStrings[altIndex] += ") : ["; andrew@2: tempoUpdateStrings[altIndex] += ofToString(altIndex); andrew@2: tempoUpdateStrings[altIndex] += "]] : "; andrew@2: tempoUpdateStrings[altIndex] += ofToString(timeInterval); andrew@2: tempoUpdateStrings[altIndex] += ", ioi:"; andrew@2: tempoUpdateStrings[altIndex] += ofToString(i); andrew@2: //tempoUpdateStrings[altIndex] += ""; andrew@2: andrew@2: } andrew@2: andrew@2: } andrew@2: andrew@2: double testInterval = timeInterval / 16;//pow(2, i);//pow(2.0, i); andrew@2: if (updateTempoIfWithinRange(testInterval)){ andrew@2: beatTimes.intervalUsed[beatTimes.index][altIndex] = true; andrew@2: beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval; andrew@2: } andrew@2: andrew@2: }else{ andrew@2: //OLD VERSON andrew@2: //THIS USES THE CURRENT TEMPO ESTIMATE TO DECIDE WHAT THE BEST INTERVAL IS andrew@2: //&& integerMultipleOfTatum % 2 == 0 removed below XXX put back andrew@2: if (altIndex != beatTimes.index && integerMultipleOfTatum < 17 andrew@2: && integerMultipleOfTatum > 0 && beatTimes.startIndex > 8//beattimes.index > 8 - the start andrew@2: && integerMultipleOfTatum%2 == 0){//mod 2 - i.e. proper beat intervals only andrew@2: andrew@2: double testInterval = timeInterval / integerMultipleOfTatum; andrew@2: andrew@2: if (updateTempoIfWithinRange(testInterval)){ andrew@2: andrew@2: beatTimes.intervalUsed[beatTimes.index][altIndex] = true; andrew@2: beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval; andrew@2: andrew@2: if (paused == false){ andrew@2: tempoUpdateStrings[altIndex] = "Tempo Updates : ("; andrew@2: tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0); andrew@2: tempoUpdateStrings[altIndex] += ") : ["; andrew@2: tempoUpdateStrings[altIndex] += ofToString(altIndex, 0); andrew@2: tempoUpdateStrings[altIndex] += "] :: "; andrew@2: tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum); andrew@2: tempoUpdateStrings[altIndex] += " intervals :: "; andrew@2: tempoUpdateStrings[altIndex] += ofToString(tempoInterval); andrew@2: tempoUpdateStrings[altIndex] += " ms."; andrew@2: // tempoUpdateStrings[altIndex] += ", ioi:"; andrew@2: andrew@2: // tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum); andrew@2: andrew@2: andrew@2: andrew@2: andrew@2: }//end if not paused andrew@2: andrew@2: andrew@2: }//end if good interval to update andrew@2: andrew@2: }//end if not same index etc andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: }//end for all intervals andrew@2: andrew@2: sendMaxTempo(); andrew@2: }//end if new beat time andrew@2: double tempoEstimate = tempoDistribution.getIntegratedEstimateIndex(); andrew@2: tempoDistribution.calculateStandardDeviation(); andrew@2: tempoStdDev = tempoDistribution.standardDeviation; andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: bool testApp::updateTempoIfWithinRange(double timeInterval){ andrew@2: andrew@2: bool updated = false; andrew@2: andrew@2: if (timeInterval > tempoMinimum && timeInterval < tempoMaximum ){ andrew@2: calculateTempoUpdate(timeInterval); andrew@2: updated = true; andrew@2: } andrew@2: andrew@2: return updated; andrew@2: } andrew@2: andrew@2: andrew@2: */ andrew@2: //end andrew@2: /* andrew@2: void testApp::calculateTempoUpdate(double tempoInterval){ andrew@2: andrew@2: andrew@2: tempoDistribution.resetPrior(); andrew@2: //need to relook at likelihood for the tempo distribution - not the same as.... andrew@10: tempoDistribution.setGaussianLikelihood(drumTracker.arraySize * (tempoInterval-tempoMinimum)/(tempoMaximum - tempoMinimum), tempoDistribution.likelihoodStdDev); andrew@2: tempoDistribution.calculatePosterior(); andrew@2: tempoDistribution.renormalisePosterior(); andrew@2: andrew@2: //did take pic of screen here - see initialiser4 andrew@2: } andrew@2: */ andrew@2: andrew@6: /* andrew@6: beatDistribution.initialiseArray(); andrew@6: tempoDistribution.initialiseArray(); andrew@6: beatTimes.lastBeatTime = 0; andrew@6: correctionFactor = 0.5; andrew@6: andrew@6: andrew@6: andrew@10: tempoDistribution.likelihoodStdDev = drumTracker.arraySize / 32; andrew@6: // tempoDistribution.likelihoodNoise = 0.96; andrew@6: tempoDistribution.likelihoodNoise = 0.7; andrew@10: tempoDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/1);//wide andrew@6: andrew@10: beatDistribution.likelihoodStdDev = drumTracker.arraySize / 32; andrew@6: beatDistribution.likelihoodNoise = 0.56; andrew@10: beatDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/1); andrew@6: andrew@6: andrew@6: tempoMinimum = 180; andrew@6: tempoMaximum = 400; andrew@6: posteriorMaximum = 0.1; andrew@6: andrew@6: */ andrew@6: andrew@6: /* andrew@6: beatTimes.startIndex = 0; andrew@6: beatTimes.lastBeatTime = 0; andrew@6: maxPhase = 0; andrew@6: posteriorMaximum = 0.1; andrew@6: andrew@6: accompanimentStarted = false; andrew@6: andrew@6: tempoDistribution.likelihoodNoise = 0.8; andrew@10: tempoDistribution.setGaussianPrior(drumTracker.arraySize/2, drumTracker.arraySize/2);//wide andrew@6: andrew@6: beatDistribution.initialiseArray(); andrew@6: tempoDistribution.initialiseArray(); andrew@6: andrew@6: tempoDistribution.calculateStandardDeviation(); andrew@6: beatDistribution.calculateStandardDeviation(); andrew@6: andrew@6: tempoStdDev = tempoDistribution.standardDeviation; andrew@6: andrew@6: beatTimes.resetBeatTimeArray(); andrew@6: */