andrew@2
|
1 /*
|
andrew@2
|
2 * beatTempo.cpp
|
andrew@2
|
3 * bayesianTempo1
|
andrew@2
|
4 *
|
andrew@2
|
5 * Created by Andrew Robertson on 08/05/2010.
|
andrew@2
|
6 * Copyright 2010 __MyCompanyName__. All rights reserved.
|
andrew@2
|
7 *
|
andrew@2
|
8 */
|
andrew@2
|
9
|
andrew@2
|
10 #include "beatTempo.h"
|
andrew@2
|
11
|
andrew@2
|
12 beatTempo::beatTempo(){
|
andrew@2
|
13 index = 0;
|
andrew@2
|
14 lastBeatTime = 0;
|
andrew@2
|
15 decayAmount = 0;
|
andrew@2
|
16 }
|
andrew@2
|
17
|
andrew@2
|
18 //records a loop of cpu times for the last 16 events received
|
andrew@2
|
19
|
andrew@2
|
20 void beatTempo::addBeatTime(double f, int type){
|
andrew@2
|
21 //type 1 is kick, type 2 is snare
|
andrew@2
|
22
|
andrew@2
|
23 index++;
|
andrew@2
|
24 startIndex++;
|
andrew@2
|
25 if (index == 16){
|
andrew@2
|
26 index = 0;
|
andrew@2
|
27 }
|
andrew@2
|
28 lastBeatTime = f;
|
andrew@2
|
29 beatTimes[index] = f;
|
andrew@2
|
30
|
andrew@2
|
31 //find the closest click time to this new cputime
|
andrew@2
|
32 //NOT ACTUALLY USED ANYWHERE....
|
andrew@2
|
33 //double useThisClickTime = lastClickTime;
|
andrew@2
|
34 //int useThisClickIndex = lastClickIndex ;
|
andrew@2
|
35
|
andrew@2
|
36 if (lastClickTime + (tatum/2) < f){
|
andrew@2
|
37 //next click time
|
andrew@2
|
38 closestClickIndexToBeat[index] = lastClickIndex + 1;
|
andrew@2
|
39 //useThisClickTime += tatum;
|
andrew@2
|
40 // useThisClickIndex++;
|
andrew@2
|
41 }
|
andrew@2
|
42 else{
|
andrew@2
|
43 //recent click time
|
andrew@2
|
44 closestClickIndexToBeat[index] = lastClickIndex;
|
andrew@2
|
45 }
|
andrew@2
|
46 //end not used
|
andrew@2
|
47
|
andrew@2
|
48
|
andrew@2
|
49 int lastBeatSegment = beatSegment;
|
andrew@2
|
50
|
andrew@2
|
51 //timeDifference = f - lastClickTime;
|
andrew@2
|
52 timeDifference = f - lastClickTime;
|
andrew@2
|
53 //[0, 1] => [0, 2*tatum]
|
andrew@2
|
54 beatSegment = (6*(lastClickIndex%8));
|
andrew@2
|
55 beatSegment += ( ( (int)floor( ( ( (timeDifference + (tatum/12)) * 6) ) / tatum) ) );
|
andrew@2
|
56
|
andrew@2
|
57
|
andrew@2
|
58
|
andrew@2
|
59 //this calculates the probabilities of events in the different zones
|
andrew@2
|
60 //not yet used in the algorithm
|
andrew@2
|
61 beatSegment = beatSegment%48;
|
andrew@2
|
62 //wipe old onez
|
andrew@2
|
63 while (lastBeatSegment%48 != beatSegment){
|
andrew@2
|
64 lastBeatSegment++;
|
andrew@2
|
65 if (lastBeatSegment%12 == 0)
|
andrew@2
|
66 decayProbabilityDistributionRow((lastBeatSegment/12)%4);
|
andrew@2
|
67
|
andrew@2
|
68 beatMap[lastBeatSegment%48] = 0;
|
andrew@2
|
69
|
andrew@2
|
70 }
|
andrew@2
|
71 addToProbabilityDistribution(beatSegment, type);
|
andrew@2
|
72 //end of new addition
|
andrew@2
|
73
|
andrew@2
|
74 beatMap[beatSegment] = type;
|
andrew@2
|
75
|
andrew@2
|
76
|
andrew@2
|
77
|
andrew@2
|
78 double intervalCalculation;
|
andrew@2
|
79 int otherIndex;
|
andrew@2
|
80 for (otherIndex = 0;otherIndex < 16;otherIndex++){
|
andrew@2
|
81
|
andrew@2
|
82 if (otherIndex != index){
|
andrew@2
|
83 intervalCalculation = calculateInterval(index, otherIndex);
|
andrew@2
|
84 relativeIntervals[otherIndex][0] = intervalCalculation;
|
andrew@2
|
85 intervalDifferences[index][otherIndex] = intervalCalculation;
|
andrew@2
|
86
|
andrew@2
|
87 //integer multiple is relativeIntervals[otherIndex][1]
|
andrew@2
|
88 }
|
andrew@2
|
89 else{
|
andrew@2
|
90 intervalDifferences[index][otherIndex] = 0;
|
andrew@2
|
91 }
|
andrew@2
|
92 }
|
andrew@2
|
93
|
andrew@2
|
94
|
andrew@2
|
95
|
andrew@2
|
96 }
|
andrew@2
|
97
|
andrew@2
|
98
|
andrew@2
|
99 void beatTempo::addToProbabilityDistribution(int beatSegment, int type){
|
andrew@2
|
100 //printf("beat segment %i\n", beatSegment);
|
andrew@2
|
101 int beatNumber = (int) (beatSegment + 1)/12;
|
andrew@2
|
102 beatNumber = beatNumber%4;
|
andrew@2
|
103 float newProbabilityContribution = 1 - decayAmount;
|
andrew@2
|
104 switch (beatSegment%12) {
|
andrew@2
|
105 case 0:
|
andrew@2
|
106 beatProbabilityDistribution[beatNumber][0][type - 1] = newProbabilityContribution;
|
andrew@2
|
107 break;
|
andrew@2
|
108 case 1:
|
andrew@2
|
109 beatProbabilityDistribution[beatNumber][0][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
110 break;
|
andrew@2
|
111 case 2:
|
andrew@2
|
112 beatProbabilityDistribution[beatNumber][0][type - 1] = 0.5*newProbabilityContribution;
|
andrew@2
|
113 beatProbabilityDistribution[beatNumber][1][type - 1] = 0.5*newProbabilityContribution;
|
andrew@2
|
114 break;
|
andrew@2
|
115 case 3:
|
andrew@2
|
116 beatProbabilityDistribution[beatNumber][1][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
117 break;
|
andrew@2
|
118 case 4:
|
andrew@2
|
119 beatProbabilityDistribution[beatNumber][1][type - 1] = 0.4*newProbabilityContribution;
|
andrew@2
|
120 beatProbabilityDistribution[beatNumber][2][type - 1] = 0.6*newProbabilityContribution;
|
andrew@2
|
121 break;
|
andrew@2
|
122 case 5:
|
andrew@2
|
123 beatProbabilityDistribution[beatNumber][2][type - 1] = 0.4*newProbabilityContribution;
|
andrew@2
|
124 beatProbabilityDistribution[beatNumber][3][type - 1] = 0.6*newProbabilityContribution;
|
andrew@2
|
125 break;
|
andrew@2
|
126 case 6:
|
andrew@2
|
127 beatProbabilityDistribution[beatNumber][3][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
128 break;
|
andrew@2
|
129 case 7:
|
andrew@2
|
130 beatProbabilityDistribution[beatNumber][3][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
131 break;
|
andrew@2
|
132 case 8:
|
andrew@2
|
133 beatProbabilityDistribution[beatNumber][4][type - 1] = 0.6*newProbabilityContribution;
|
andrew@2
|
134 beatProbabilityDistribution[beatNumber][5][type - 1] = 0.4*newProbabilityContribution;
|
andrew@2
|
135 break;
|
andrew@2
|
136 case 9:
|
andrew@2
|
137 beatProbabilityDistribution[beatNumber][5][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
138 break;
|
andrew@2
|
139 case 10:
|
andrew@2
|
140 beatProbabilityDistribution[beatNumber][5][type - 1] = 0.5*newProbabilityContribution;
|
andrew@2
|
141 break;
|
andrew@2
|
142 case 11:
|
andrew@2
|
143 beatProbabilityDistribution[(beatNumber+1)%4][0][type - 1] = 1*newProbabilityContribution;
|
andrew@2
|
144 break;
|
andrew@2
|
145 }
|
andrew@2
|
146
|
andrew@2
|
147
|
andrew@2
|
148 }
|
andrew@2
|
149
|
andrew@2
|
150 void beatTempo::decayProbabilityDistributionRow(int row){
|
andrew@2
|
151
|
andrew@2
|
152 for (int x = 0;x<6;x++){
|
andrew@2
|
153 beatProbabilityDistribution[row][x][0] *= decayAmount;
|
andrew@2
|
154 beatProbabilityDistribution[row][x][1] *= decayAmount;
|
andrew@2
|
155 }
|
andrew@2
|
156
|
andrew@2
|
157
|
andrew@2
|
158 }
|
andrew@2
|
159
|
andrew@2
|
160 double beatTempo::calculateInterval(int newIndex, int otherIndex){
|
andrew@2
|
161
|
andrew@2
|
162 double newTime, otherTime, interval, relativeInterval;
|
andrew@2
|
163 relativeInterval = tatum;
|
andrew@2
|
164 int tatumMultiple;
|
andrew@2
|
165 newTime = beatTimes[newIndex];
|
andrew@2
|
166 otherTime = beatTimes[otherIndex];
|
andrew@2
|
167 if (otherTime > 0){
|
andrew@2
|
168 interval = newTime - otherTime;
|
andrew@2
|
169 // tatumMultiple = closestClickIndexToBeat[newIndex] - closestClickIndexToBeat[otherIndex]; - to be added
|
andrew@2
|
170 tatumMultiple = round (interval / tatum);
|
andrew@2
|
171 if (tatumMultiple > 0){
|
andrew@2
|
172 relativeInterval = interval / (tatumMultiple);
|
andrew@2
|
173 relativeIntervals[otherIndex][1] = tatumMultiple;
|
andrew@2
|
174 tatumMultiples[newIndex][otherIndex] = tatumMultiple;
|
andrew@2
|
175 }//end if
|
andrew@2
|
176 }
|
andrew@2
|
177 return relativeInterval;
|
andrew@2
|
178
|
andrew@2
|
179 }
|
andrew@2
|
180
|
andrew@2
|
181
|
andrew@2
|
182 void beatTempo::resetBeatTimeArray(){
|
andrew@2
|
183 for (int i = 0;i < 16;i++){
|
andrew@2
|
184 beatTimes[i] = 0;
|
andrew@2
|
185 for (int k = 0;k < 16;k++)
|
andrew@2
|
186 intervalDifferences[i][k] = 0;
|
andrew@2
|
187 }
|
andrew@2
|
188 } |