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