andrew@2: /* andrew@2: * beatTempo.cpp andrew@2: * bayesianTempo1 andrew@2: * andrew@2: * Created by Andrew Robertson on 08/05/2010. andrew@2: * Copyright 2010 __MyCompanyName__. All rights reserved. andrew@2: * andrew@2: */ andrew@2: andrew@2: #include "beatTempo.h" andrew@2: andrew@2: beatTempo::beatTempo(){ andrew@2: index = 0; andrew@2: lastBeatTime = 0; andrew@2: decayAmount = 0; andrew@2: } andrew@2: andrew@2: //records a loop of cpu times for the last 16 events received andrew@2: andrew@2: void beatTempo::addBeatTime(double f, int type){ andrew@2: //type 1 is kick, type 2 is snare andrew@2: andrew@2: index++; andrew@2: startIndex++; andrew@2: if (index == 16){ andrew@2: index = 0; andrew@2: } andrew@2: lastBeatTime = f; andrew@2: beatTimes[index] = f; andrew@2: andrew@2: //find the closest click time to this new cputime andrew@2: //NOT ACTUALLY USED ANYWHERE.... andrew@2: //double useThisClickTime = lastClickTime; andrew@2: //int useThisClickIndex = lastClickIndex ; andrew@2: andrew@2: if (lastClickTime + (tatum/2) < f){ andrew@2: //next click time andrew@2: closestClickIndexToBeat[index] = lastClickIndex + 1; andrew@2: //useThisClickTime += tatum; andrew@2: // useThisClickIndex++; andrew@2: } andrew@2: else{ andrew@2: //recent click time andrew@2: closestClickIndexToBeat[index] = lastClickIndex; andrew@2: } andrew@2: //end not used andrew@2: andrew@2: andrew@2: int lastBeatSegment = beatSegment; andrew@2: andrew@2: //timeDifference = f - lastClickTime; andrew@2: timeDifference = f - lastClickTime; andrew@2: //[0, 1] => [0, 2*tatum] andrew@2: beatSegment = (6*(lastClickIndex%8)); andrew@2: beatSegment += ( ( (int)floor( ( ( (timeDifference + (tatum/12)) * 6) ) / tatum) ) ); andrew@2: andrew@2: andrew@2: andrew@2: //this calculates the probabilities of events in the different zones andrew@2: //not yet used in the algorithm andrew@2: beatSegment = beatSegment%48; andrew@2: //wipe old onez andrew@2: while (lastBeatSegment%48 != beatSegment){ andrew@2: lastBeatSegment++; andrew@2: if (lastBeatSegment%12 == 0) andrew@2: decayProbabilityDistributionRow((lastBeatSegment/12)%4); andrew@2: andrew@2: beatMap[lastBeatSegment%48] = 0; andrew@2: andrew@2: } andrew@2: addToProbabilityDistribution(beatSegment, type); andrew@2: //end of new addition andrew@2: andrew@2: beatMap[beatSegment] = type; andrew@2: andrew@2: andrew@2: andrew@2: double intervalCalculation; andrew@2: int otherIndex; andrew@2: for (otherIndex = 0;otherIndex < 16;otherIndex++){ andrew@2: andrew@2: if (otherIndex != index){ andrew@2: intervalCalculation = calculateInterval(index, otherIndex); andrew@2: relativeIntervals[otherIndex][0] = intervalCalculation; andrew@2: intervalDifferences[index][otherIndex] = intervalCalculation; andrew@2: andrew@2: //integer multiple is relativeIntervals[otherIndex][1] andrew@2: } andrew@2: else{ andrew@2: intervalDifferences[index][otherIndex] = 0; andrew@2: } andrew@2: } andrew@2: andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void beatTempo::addToProbabilityDistribution(int beatSegment, int type){ andrew@2: //printf("beat segment %i\n", beatSegment); andrew@2: int beatNumber = (int) (beatSegment + 1)/12; andrew@2: beatNumber = beatNumber%4; andrew@2: float newProbabilityContribution = 1 - decayAmount; andrew@2: switch (beatSegment%12) { andrew@2: case 0: andrew@2: beatProbabilityDistribution[beatNumber][0][type - 1] = newProbabilityContribution; andrew@2: break; andrew@2: case 1: andrew@2: beatProbabilityDistribution[beatNumber][0][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: case 2: andrew@2: beatProbabilityDistribution[beatNumber][0][type - 1] = 0.5*newProbabilityContribution; andrew@2: beatProbabilityDistribution[beatNumber][1][type - 1] = 0.5*newProbabilityContribution; andrew@2: break; andrew@2: case 3: andrew@2: beatProbabilityDistribution[beatNumber][1][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: case 4: andrew@2: beatProbabilityDistribution[beatNumber][1][type - 1] = 0.4*newProbabilityContribution; andrew@2: beatProbabilityDistribution[beatNumber][2][type - 1] = 0.6*newProbabilityContribution; andrew@2: break; andrew@2: case 5: andrew@2: beatProbabilityDistribution[beatNumber][2][type - 1] = 0.4*newProbabilityContribution; andrew@2: beatProbabilityDistribution[beatNumber][3][type - 1] = 0.6*newProbabilityContribution; andrew@2: break; andrew@2: case 6: andrew@2: beatProbabilityDistribution[beatNumber][3][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: case 7: andrew@2: beatProbabilityDistribution[beatNumber][3][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: case 8: andrew@2: beatProbabilityDistribution[beatNumber][4][type - 1] = 0.6*newProbabilityContribution; andrew@2: beatProbabilityDistribution[beatNumber][5][type - 1] = 0.4*newProbabilityContribution; andrew@2: break; andrew@2: case 9: andrew@2: beatProbabilityDistribution[beatNumber][5][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: case 10: andrew@2: beatProbabilityDistribution[beatNumber][5][type - 1] = 0.5*newProbabilityContribution; andrew@2: break; andrew@2: case 11: andrew@2: beatProbabilityDistribution[(beatNumber+1)%4][0][type - 1] = 1*newProbabilityContribution; andrew@2: break; andrew@2: } andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: void beatTempo::decayProbabilityDistributionRow(int row){ andrew@2: andrew@2: for (int x = 0;x<6;x++){ andrew@2: beatProbabilityDistribution[row][x][0] *= decayAmount; andrew@2: beatProbabilityDistribution[row][x][1] *= decayAmount; andrew@2: } andrew@2: andrew@2: andrew@2: } andrew@2: andrew@2: double beatTempo::calculateInterval(int newIndex, int otherIndex){ andrew@2: andrew@2: double newTime, otherTime, interval, relativeInterval; andrew@2: relativeInterval = tatum; andrew@2: int tatumMultiple; andrew@2: newTime = beatTimes[newIndex]; andrew@2: otherTime = beatTimes[otherIndex]; andrew@2: if (otherTime > 0){ andrew@2: interval = newTime - otherTime; andrew@2: // tatumMultiple = closestClickIndexToBeat[newIndex] - closestClickIndexToBeat[otherIndex]; - to be added andrew@2: tatumMultiple = round (interval / tatum); andrew@2: if (tatumMultiple > 0){ andrew@2: relativeInterval = interval / (tatumMultiple); andrew@2: relativeIntervals[otherIndex][1] = tatumMultiple; andrew@2: tatumMultiples[newIndex][otherIndex] = tatumMultiple; andrew@2: }//end if andrew@2: } andrew@2: return relativeInterval; andrew@2: andrew@2: } andrew@2: andrew@2: andrew@2: void beatTempo::resetBeatTimeArray(){ andrew@2: for (int i = 0;i < 16;i++){ andrew@2: beatTimes[i] = 0; andrew@2: for (int k = 0;k < 16;k++) andrew@2: intervalDifferences[i][k] = 0; andrew@2: } andrew@2: }