|
andrew@2
|
1 #include "testApp.h"
|
|
andrew@2
|
2
|
|
andrew@2
|
3
|
|
andrew@2
|
4 //--------------------------------------------------------------
|
|
andrew@2
|
5 //relooking at this problem
|
|
andrew@2
|
6 //bayesianTempo7 - have had working well with Bayesian8NEW maxmsp set
|
|
andrew@2
|
7
|
|
andrew@2
|
8 //updated in bayesian8
|
|
andrew@2
|
9 //integrate so that maxPhase and tempo are the integrated result across the pdf
|
|
andrew@2
|
10 //rather tahn the maximum index - tends to reflect the actuial distribution better
|
|
andrew@2
|
11 //and is the "correct" bayesian method
|
|
andrew@2
|
12
|
|
andrew@2
|
13 //added [ and ] tpo change the alignment when rescue is needed
|
|
andrew@2
|
14
|
|
andrew@2
|
15 //in Bayesian9 (BayesianTest8NEW)
|
|
andrew@2
|
16 //added noise in phase process
|
|
andrew@2
|
17 //started probability distribution for observed beat events
|
|
andrew@2
|
18
|
|
andrew@2
|
19 //in bayesian 11
|
|
andrew@2
|
20 //get s.d. of posterior
|
|
andrew@2
|
21 //this is set to be used as the s.d. of the likelihood
|
|
andrew@2
|
22
|
|
andrew@2
|
23
|
|
andrew@2
|
24 //Initialiser : the algorithm has an initialisation stage with flat prior that detects liekly tempo
|
|
andrew@2
|
25
|
|
andrew@2
|
26
|
|
andrew@2
|
27
|
|
andrew@2
|
28 //BAYESIAN DISTRIBUTION SET by class BayesianArray
|
|
andrew@2
|
29 //SETUP - initialises array
|
|
andrew@2
|
30 //UPDATE - decay the distribution with noise
|
|
andrew@2
|
31 //this should be done using tempo and noise
|
|
andrew@2
|
32 //DRAW - Draw current distributions and also the maximum
|
|
andrew@2
|
33
|
|
andrew@2
|
34 //Runs with bayesian11NEW
|
|
andrew@2
|
35 //and B-KeeperOldBayesianTestNew in Live
|
|
andrew@2
|
36 //Needs - categorisation of beats and tempo
|
|
andrew@2
|
37 //can we use our distribution to filter the input or is that cheating?
|
|
andrew@2
|
38
|
|
andrew@2
|
39 //INtroduce lock scheme for tempo - we know where the beat fell, so can calculate the appropriate tempo interval
|
|
andrew@2
|
40
|
|
andrew@2
|
41 void testApp::setup(){
|
|
andrew@2
|
42 // listen on the given port
|
|
andrew@2
|
43 cout << "listening for osc messages on port " << PORT << "\n";
|
|
andrew@2
|
44 receiver.setup( PORT );
|
|
andrew@2
|
45
|
|
andrew@2
|
46 // sender.setup( HOST, OUTPORT );
|
|
andrew@2
|
47 ofSetCircleResolution(50);
|
|
andrew@2
|
48 ofBackground(255,255,255);
|
|
andrew@2
|
49 bSmooth = false;
|
|
andrew@2
|
50 msg_string = "setup";
|
|
andrew@2
|
51
|
|
andrew@2
|
52 ofSetWindowTitle("Bayesian Test");
|
|
andrew@2
|
53
|
|
andrew@2
|
54 ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps.
|
|
andrew@2
|
55
|
|
andrew@2
|
56 KLdiv = 0;
|
|
andrew@3
|
57 entropy = 0;
|
|
andrew@2
|
58 /*
|
|
andrew@2
|
59 beatDistribution.initialiseArray();
|
|
andrew@2
|
60 tempoDistribution.initialiseArray();
|
|
andrew@2
|
61 beatTimes.lastBeatTime = 0;
|
|
andrew@2
|
62 correctionFactor = 0.5;
|
|
andrew@2
|
63
|
|
andrew@2
|
64
|
|
andrew@2
|
65
|
|
andrew@2
|
66 tempoDistribution.likelihoodStdDev = ARRAY_SIZE / 32;
|
|
andrew@2
|
67 // tempoDistribution.likelihoodNoise = 0.96;
|
|
andrew@2
|
68 tempoDistribution.likelihoodNoise = 0.7;
|
|
andrew@2
|
69 tempoDistribution.setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);//wide
|
|
andrew@2
|
70
|
|
andrew@2
|
71 beatDistribution.likelihoodStdDev = ARRAY_SIZE / 32;
|
|
andrew@2
|
72 beatDistribution.likelihoodNoise = 0.56;
|
|
andrew@2
|
73 beatDistribution.setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);
|
|
andrew@2
|
74
|
|
andrew@2
|
75
|
|
andrew@2
|
76 tempoMinimum = 180;
|
|
andrew@2
|
77 tempoMaximum = 400;
|
|
andrew@2
|
78 posteriorMaximum = 0.1;
|
|
andrew@2
|
79
|
|
andrew@2
|
80 */
|
|
andrew@2
|
81 hidePriorMode = false;
|
|
andrew@2
|
82
|
|
andrew@2
|
83 printInterval = true;
|
|
andrew@2
|
84 drawData = false;
|
|
andrew@2
|
85
|
|
andrew@2
|
86 screenToDraw = 0;
|
|
andrew@2
|
87
|
|
andrew@2
|
88 ofSetLineWidth(2);
|
|
andrew@2
|
89 ofEnableSmoothing();
|
|
andrew@2
|
90
|
|
andrew@2
|
91
|
|
andrew@2
|
92 bSnapshot = false;
|
|
andrew@2
|
93 snapCounter = 0;
|
|
andrew@2
|
94
|
|
andrew@2
|
95 drumTracker.paused = false;
|
|
andrew@2
|
96
|
|
andrew@2
|
97 // setDistributionOnStartTempo = true;
|
|
andrew@2
|
98
|
|
andrew@2
|
99 resetParameters();
|
|
andrew@2
|
100
|
|
andrew@2
|
101 arrayToMsecScaleFactor = (drumTracker.tempoMaximum - drumTracker.tempoMinimum)/ ARRAY_SIZE;//turns array into ms
|
|
andrew@2
|
102 tempoWindowMinimum = 100;
|
|
andrew@2
|
103 tempoWindowMaximum = 150;
|
|
andrew@2
|
104 tempoWindowWidth = 50;
|
|
andrew@2
|
105 }
|
|
andrew@2
|
106
|
|
andrew@2
|
107
|
|
andrew@2
|
108 void testApp::resetParameters(){
|
|
andrew@2
|
109 /*
|
|
andrew@2
|
110 beatTimes.startIndex = 0;
|
|
andrew@2
|
111 beatTimes.lastBeatTime = 0;
|
|
andrew@2
|
112 maxPhase = 0;
|
|
andrew@2
|
113 posteriorMaximum = 0.1;
|
|
andrew@2
|
114
|
|
andrew@2
|
115 accompanimentStarted = false;
|
|
andrew@2
|
116
|
|
andrew@2
|
117 tempoDistribution.likelihoodNoise = 0.8;
|
|
andrew@2
|
118 tempoDistribution.setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/2);//wide
|
|
andrew@2
|
119
|
|
andrew@2
|
120 beatDistribution.initialiseArray();
|
|
andrew@2
|
121 tempoDistribution.initialiseArray();
|
|
andrew@2
|
122
|
|
andrew@2
|
123 tempoDistribution.calculateStandardDeviation();
|
|
andrew@2
|
124 beatDistribution.calculateStandardDeviation();
|
|
andrew@2
|
125
|
|
andrew@2
|
126 tempoStdDev = tempoDistribution.standardDeviation;
|
|
andrew@2
|
127
|
|
andrew@2
|
128 beatTimes.resetBeatTimeArray();
|
|
andrew@2
|
129 */
|
|
andrew@2
|
130 }
|
|
andrew@2
|
131
|
|
andrew@2
|
132 //--------------------------------------------------------------
|
|
andrew@2
|
133 void testApp::update(){
|
|
andrew@2
|
134
|
|
andrew@2
|
135
|
|
andrew@2
|
136 updateOSCmessages();
|
|
andrew@2
|
137
|
|
andrew@2
|
138 //update tempo window range - this for viewing tempo closeup
|
|
andrew@2
|
139 while (tempoWindowMinimum + tempoWindowWidth/4 > drumTracker.tempoDistribution.integratedEstimate)
|
|
andrew@2
|
140 tempoWindowMinimum -= tempoWindowWidth/4;
|
|
andrew@2
|
141
|
|
andrew@2
|
142 while (tempoWindowMinimum + 3*tempoWindowWidth/4 < drumTracker.tempoDistribution.integratedEstimate)
|
|
andrew@2
|
143 tempoWindowMinimum += tempoWindowWidth/4;
|
|
andrew@2
|
144
|
|
andrew@2
|
145 tempoWindowMaximum = tempoWindowMinimum + tempoWindowWidth;
|
|
andrew@2
|
146
|
|
andrew@2
|
147 drumTracker.decayDistributions();
|
|
andrew@2
|
148
|
|
andrew@2
|
149 }
|
|
andrew@2
|
150
|
|
andrew@2
|
151
|
|
andrew@2
|
152 void testApp::updateOSCmessages(){
|
|
andrew@2
|
153
|
|
andrew@2
|
154
|
|
andrew@2
|
155 // check for waiting messages
|
|
andrew@2
|
156 while( receiver.hasWaitingMessages() )
|
|
andrew@2
|
157 {
|
|
andrew@2
|
158 ofxOscMessage m;
|
|
andrew@2
|
159 receiver.getNextMessage( &m );
|
|
andrew@2
|
160 string newAddress = m.getAddress();
|
|
andrew@2
|
161
|
|
andrew@2
|
162 if ( m.getAddress() == "/Reset" ){
|
|
andrew@2
|
163 printf("baysian reset\n");
|
|
andrew@2
|
164 drumTracker.resetParameters();
|
|
andrew@2
|
165 }
|
|
andrew@2
|
166
|
|
andrew@2
|
167
|
|
andrew@2
|
168 if ( m.getAddress() == "/beatError" ){
|
|
andrew@2
|
169 double timeNow = ofGetElapsedTimeMillis();
|
|
andrew@2
|
170 if (timeNow - drumTracker.setBeatToNowTime > 1000)
|
|
andrew@2
|
171 drumTracker.newKickError(m.getArgAsFloat(0), m.getArgAsFloat(2), m.getArgAsString(1));
|
|
andrew@2
|
172 KLdiv = drumTracker.beatDistribution.getKLdivergence();
|
|
andrew@3
|
173 entropy = drumTracker.beatDistribution.getEntropyOfPosterior();
|
|
andrew@4
|
174 recentError = m.getArgAsFloat(0);
|
|
andrew@4
|
175 drumType = m.getArgAsString(1);
|
|
andrew@4
|
176 }//end if new error
|
|
andrew@2
|
177
|
|
andrew@2
|
178
|
|
andrew@2
|
179
|
|
andrew@2
|
180 if ( m.getAddress() == "/tatum" ){
|
|
andrew@2
|
181 drumTracker.beatTimes.tatum = m.getArgAsFloat(0);
|
|
andrew@2
|
182 printf("got tatum as %f\n", m.getArgAsFloat(0));
|
|
andrew@2
|
183 }
|
|
andrew@2
|
184
|
|
andrew@2
|
185 if ( m.getAddress() == "/startTatum" ){
|
|
andrew@2
|
186 drumTracker.startTatum(m.getArgAsFloat(0));
|
|
andrew@2
|
187 printf("START TATUM %f\n", m.getArgAsFloat(0));
|
|
andrew@2
|
188 //then change so tempo distribution is correct....
|
|
andrew@2
|
189 }//end start tatum
|
|
andrew@2
|
190
|
|
andrew@2
|
191
|
|
andrew@2
|
192 if ( m.getAddress() == "/uniformTempo" ){
|
|
andrew@2
|
193 drumTracker.setUniformTempo();
|
|
andrew@2
|
194
|
|
andrew@2
|
195 }
|
|
andrew@2
|
196
|
|
andrew@2
|
197
|
|
andrew@2
|
198 if ( m.getAddress() == "/uniformPhase" ){
|
|
andrew@2
|
199 drumTracker.setUniformPhase();
|
|
andrew@2
|
200
|
|
andrew@2
|
201 }
|
|
andrew@2
|
202
|
|
andrew@2
|
203
|
|
andrew@2
|
204 if ( m.getAddress() == "/setBeatNow" ){
|
|
andrew@2
|
205
|
|
andrew@2
|
206 double beatTime = m.getArgAsFloat(0);
|
|
andrew@2
|
207 drumTracker.setBeatNow(beatTime);
|
|
andrew@2
|
208 //printf("SET BEAT NOW %f\n", beatTime);
|
|
andrew@2
|
209 }
|
|
andrew@2
|
210
|
|
andrew@2
|
211
|
|
andrew@2
|
212 if ( m.getAddress() == "/clickindex" ){
|
|
andrew@2
|
213
|
|
andrew@2
|
214 int clickIndex = m.getArgAsInt32(0);
|
|
andrew@2
|
215 float clickTime = m.getArgAsFloat(1);
|
|
andrew@2
|
216 drumTracker.setNewClickIndex(clickIndex, clickTime);
|
|
andrew@2
|
217 }
|
|
andrew@2
|
218
|
|
andrew@2
|
219
|
|
andrew@2
|
220 if ( m.getAddress() == "/newBeat" ){
|
|
andrew@2
|
221 int beatIndex = m.getArgAsInt32(0);
|
|
andrew@2
|
222 drumTracker.newBeat(beatIndex);
|
|
andrew@2
|
223 }
|
|
andrew@2
|
224
|
|
andrew@2
|
225
|
|
andrew@2
|
226 if ( m.getAddress() == "/beatCorrection" )
|
|
andrew@2
|
227 {
|
|
andrew@2
|
228 float beatCorrValue = m.getArgAsFloat(0);
|
|
andrew@2
|
229 drumTracker.doBeatCorrection(beatCorrValue);
|
|
andrew@2
|
230
|
|
andrew@2
|
231 }//end correction by
|
|
andrew@2
|
232
|
|
andrew@2
|
233
|
|
andrew@2
|
234 if ( m.getAddress() == "/BayesianNoise" ){
|
|
andrew@2
|
235 drumTracker.beatDistribution.likelihoodNoise = m.getArgAsFloat(0);;
|
|
andrew@2
|
236 printf("bayesian noise set to %f\n", drumTracker.beatDistribution.likelihoodNoise);
|
|
andrew@2
|
237 // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev);
|
|
andrew@2
|
238 }
|
|
andrew@2
|
239
|
|
andrew@2
|
240 if ( m.getAddress() == "/BayesianStdDev" ){
|
|
andrew@2
|
241 drumTracker.beatDistribution.likelihoodStdDev = ARRAY_SIZE / m.getArgAsFloat(0);
|
|
andrew@2
|
242 // beatDistribution.setGaussianLikelihood(beatDistribution.likelihoodMean, beatDistribution.likelihoodStdDev);
|
|
andrew@2
|
243 }
|
|
andrew@2
|
244
|
|
andrew@2
|
245
|
|
andrew@2
|
246 }//end while there is new message
|
|
andrew@2
|
247
|
|
andrew@2
|
248
|
|
andrew@2
|
249 }
|
|
andrew@2
|
250
|
|
andrew@2
|
251
|
|
andrew@2
|
252 void testApp::takePictureOfScreen(){
|
|
andrew@2
|
253 // grab a rectangle at 200,200, width and height of 300,180
|
|
andrew@2
|
254 img.grabScreen(0,0,screenWidth,screenHeight);
|
|
andrew@2
|
255 char fileName[255];
|
|
andrew@2
|
256 sprintf(fileName, "snapshot_%0.3i.png", snapCounter);
|
|
andrew@2
|
257 img.saveImage(fileName);
|
|
andrew@2
|
258 //printf("saved %s\n", fileName);
|
|
andrew@2
|
259 snapCounter++;
|
|
andrew@2
|
260 bSnapshot = false;
|
|
andrew@2
|
261 }
|
|
andrew@2
|
262
|
|
andrew@2
|
263 /*
|
|
andrew@2
|
264 void testApp::setBeatDistribution(int beatPosition){
|
|
andrew@2
|
265 switch (beatPosition){
|
|
andrew@2
|
266 //early sixteenth is that the beat is a sixteenth earlier
|
|
andrew@2
|
267 case 0:
|
|
andrew@2
|
268 case 1:
|
|
andrew@2
|
269 case 11:
|
|
andrew@2
|
270 //i.e. these zones are interpreted as "on the beat"
|
|
andrew@2
|
271 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
272 beatDistribution.earlySixteenthNoteProportion = 0;
|
|
andrew@2
|
273 beatDistribution.lateSixteenthNoteProportion = 0;
|
|
andrew@2
|
274 break;
|
|
andrew@2
|
275 //10 and 2 were here
|
|
andrew@2
|
276
|
|
andrew@2
|
277 case 2:
|
|
andrew@2
|
278 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
279 beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
|
|
andrew@2
|
280 //i.e. a 25% chance it is early sixteenth - 75% that the beat actually lies here
|
|
andrew@2
|
281 beatDistribution.lateSixteenthNoteProportion = 0;
|
|
andrew@2
|
282 break;
|
|
andrew@2
|
283
|
|
andrew@2
|
284 case 3:
|
|
andrew@2
|
285 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
286 beatDistribution.earlySixteenthNoteProportion = 0.3;//was 0.4 in Bayesian8 //half chance it is early
|
|
andrew@2
|
287 beatDistribution.lateSixteenthNoteProportion = 0;
|
|
andrew@2
|
288 break;
|
|
andrew@2
|
289
|
|
andrew@2
|
290 case 5:
|
|
andrew@2
|
291 case 6:
|
|
andrew@2
|
292 case 7:
|
|
andrew@2
|
293 beatDistribution.eighthNoteProportion = 0.3;//i.e. nearly half a chance we are on the 8th note
|
|
andrew@2
|
294 beatDistribution.earlySixteenthNoteProportion = 0;
|
|
andrew@2
|
295 beatDistribution.lateSixteenthNoteProportion = 0;
|
|
andrew@2
|
296 break;
|
|
andrew@2
|
297
|
|
andrew@2
|
298 case 4:
|
|
andrew@2
|
299 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
300 beatDistribution.earlySixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
|
|
andrew@2
|
301 beatDistribution.lateSixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8
|
|
andrew@2
|
302 //chsanged to 0.2 and 0.1 then back
|
|
andrew@2
|
303 break;
|
|
andrew@2
|
304
|
|
andrew@2
|
305 case 8:
|
|
andrew@2
|
306 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
307 beatDistribution.earlySixteenthNoteProportion = 0.05;//was 0.2 in Bayesian8
|
|
andrew@2
|
308 beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.3 in Bayesian8
|
|
andrew@2
|
309 break;
|
|
andrew@2
|
310
|
|
andrew@2
|
311 case 9:
|
|
andrew@2
|
312 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
313 beatDistribution.earlySixteenthNoteProportion = 0;
|
|
andrew@2
|
314 beatDistribution.lateSixteenthNoteProportion = 0.35;//was 0.4 in Bayesian8
|
|
andrew@2
|
315 break;
|
|
andrew@2
|
316
|
|
andrew@2
|
317 case 10:
|
|
andrew@2
|
318 beatDistribution.eighthNoteProportion = 0;
|
|
andrew@2
|
319 beatDistribution.earlySixteenthNoteProportion = 0;
|
|
andrew@2
|
320 beatDistribution.lateSixteenthNoteProportion = 0.25;//was 0.2 in Bayesian8
|
|
andrew@2
|
321 break;
|
|
andrew@2
|
322
|
|
andrew@2
|
323 }
|
|
andrew@2
|
324
|
|
andrew@2
|
325 }
|
|
andrew@2
|
326 */
|
|
andrew@2
|
327 //--------------------------------------------------------------
|
|
andrew@2
|
328 void testApp::draw(){
|
|
andrew@2
|
329 //--------------------------- lines
|
|
andrew@2
|
330 // a bunch of red lines, make them smooth if the flag is set
|
|
andrew@2
|
331
|
|
andrew@2
|
332
|
|
andrew@2
|
333
|
|
andrew@2
|
334 if (bSmooth){
|
|
andrew@2
|
335 ofEnableSmoothing();
|
|
andrew@2
|
336 }
|
|
andrew@2
|
337
|
|
andrew@2
|
338 switch (screenToDraw){
|
|
andrew@2
|
339 case 0:
|
|
andrew@2
|
340 drawBayesianDistribution();
|
|
andrew@2
|
341 break;
|
|
andrew@2
|
342 case 1:
|
|
andrew@2
|
343 drawTempoDistribution();
|
|
andrew@2
|
344 break;
|
|
andrew@2
|
345 case 2:
|
|
andrew@2
|
346 drawBeatMap();
|
|
andrew@2
|
347 break;
|
|
andrew@2
|
348 case 3:
|
|
andrew@2
|
349 // drawNormalisedLikelihood();
|
|
andrew@2
|
350 drawRestrictedTempoDistribution(tempoWindowMinimum, tempoWindowMaximum);
|
|
andrew@2
|
351 break;
|
|
andrew@2
|
352 case 4:
|
|
andrew@2
|
353 drawTempoData();
|
|
andrew@2
|
354 break;
|
|
andrew@2
|
355 case 5:
|
|
andrew@2
|
356 drawBeatProbabilityDistribution();
|
|
andrew@2
|
357 break;
|
|
andrew@2
|
358 case 6:
|
|
andrew@2
|
359 drawPosterior();
|
|
andrew@2
|
360 break;
|
|
andrew@2
|
361 case 7:
|
|
andrew@2
|
362 drawGreyscaleBayesianDistribution();
|
|
andrew@2
|
363 break;
|
|
andrew@2
|
364
|
|
andrew@2
|
365 }
|
|
andrew@2
|
366
|
|
andrew@2
|
367
|
|
andrew@2
|
368
|
|
andrew@2
|
369 if (bSnapshot == true){
|
|
andrew@2
|
370 takePictureOfScreen();
|
|
andrew@2
|
371 bSnapshot = false;
|
|
andrew@2
|
372 }
|
|
andrew@2
|
373
|
|
andrew@3
|
374
|
|
andrew@3
|
375
|
|
andrew@3
|
376 drawKLdivAndEntropy();
|
|
andrew@3
|
377
|
|
andrew@3
|
378 }//end draw
|
|
andrew@3
|
379
|
|
andrew@3
|
380
|
|
andrew@3
|
381 void testApp::drawKLdivAndEntropy(){
|
|
andrew@2
|
382 ofDrawBitmapString("KLdiv :"+ofToString(KLdiv, 3), 20, 40);
|
|
andrew@2
|
383 ofSetColor(200,0,0,160);
|
|
andrew@2
|
384 ofRect(0, ofGetHeight()*(1-KLdiv), 40, ofGetHeight()*KLdiv);
|
|
andrew@2
|
385
|
|
andrew@3
|
386 ofSetColor(0,0, 200, 160);
|
|
andrew@3
|
387 ofDrawBitmapString("Entropy :"+ofToString(entropy, 3), 20, 60);
|
|
andrew@3
|
388 double entropyDrawFactor = 0.1;
|
|
andrew@3
|
389 ofRect(60, ofGetHeight()*(1-entropy*entropyDrawFactor), 40, ofGetHeight()*entropy*entropyDrawFactor);
|
|
andrew@4
|
390
|
|
andrew@4
|
391 ofSetColor(100,0,200, 220);
|
|
andrew@4
|
392 ofDrawBitmapString("Error :"+ofToString(recentError, 3), 20, 80);
|
|
andrew@4
|
393 ofRect(120, ofGetHeight()*(1-fabs(recentError)), 40, ofGetHeight()*2*fabs(recentError));
|
|
andrew@4
|
394
|
|
andrew@4
|
395 ofSetColor(100,0,100, 220);
|
|
andrew@4
|
396 ofDrawBitmapString(drumType, 20, 0);
|
|
andrew@4
|
397
|
|
andrew@3
|
398 }
|
|
andrew@2
|
399
|
|
andrew@2
|
400
|
|
andrew@2
|
401 void testApp::drawTempoData(){
|
|
andrew@2
|
402
|
|
andrew@2
|
403 ofSetColor(0xFFFF00);
|
|
andrew@2
|
404 //yellow line in centre
|
|
andrew@2
|
405 ofLine( 0, (screenHeight/2), screenWidth, (screenHeight/2));
|
|
andrew@2
|
406
|
|
andrew@2
|
407 ofSetColor(0x0000FF);
|
|
andrew@2
|
408 int tempoIndex = 0;
|
|
andrew@2
|
409 int widthOffset = 20;
|
|
andrew@2
|
410 float stepWidth = screenWidth / 16;
|
|
andrew@2
|
411 ofDrawBitmapString("tatums : ", 600,180);
|
|
andrew@2
|
412 ofDrawBitmapString(ofToString(drumTracker.beatTimes.tatum, 1), 700,180);
|
|
andrew@2
|
413 ofDrawBitmapString("bpm : ", 600,200);
|
|
andrew@2
|
414 ofDrawBitmapString(ofToString((drumTracker.beatTimes.tatum/30000), 1), 700,200);
|
|
andrew@2
|
415 int intervalIndex;
|
|
andrew@2
|
416 int intervalWidth = 2;
|
|
andrew@2
|
417 float magnifyingFactor = 8;
|
|
andrew@2
|
418 for (tempoIndex = 0;tempoIndex < 16; tempoIndex++){
|
|
andrew@2
|
419
|
|
andrew@2
|
420 for (intervalIndex = 0;intervalIndex < 16;intervalIndex++){
|
|
andrew@2
|
421 //new color code
|
|
andrew@2
|
422 if (drumTracker.beatTimes.intervalUsed[tempoIndex][intervalIndex] == true){
|
|
andrew@2
|
423 ofSetColor(0x00FFFF);
|
|
andrew@2
|
424 }
|
|
andrew@2
|
425 else{
|
|
andrew@2
|
426 ofSetColor(0xFF00FF);
|
|
andrew@2
|
427 }
|
|
andrew@2
|
428 //end new code
|
|
andrew@2
|
429
|
|
andrew@2
|
430 ofLine((stepWidth*tempoIndex)+ (intervalWidth*intervalIndex) + widthOffset, screenHeight,
|
|
andrew@2
|
431 (stepWidth*tempoIndex) + (intervalWidth*intervalIndex) + widthOffset, (screenHeight/2) * (1 + (magnifyingFactor * (1-drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex]))));
|
|
andrew@2
|
432
|
|
andrew@2
|
433 if (printInterval == true){
|
|
andrew@2
|
434 ofDrawBitmapString(ofToString(drumTracker.beatTimes.intervalDifferences[tempoIndex][intervalIndex], 3),
|
|
andrew@2
|
435 (stepWidth*tempoIndex) + widthOffset,20+(intervalIndex*20));
|
|
andrew@2
|
436 }
|
|
andrew@2
|
437
|
|
andrew@2
|
438
|
|
andrew@2
|
439 ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][0], 3), 700,220+(tempoIndex*20));
|
|
andrew@2
|
440 ofDrawBitmapString(ofToString(drumTracker.beatTimes.relativeIntervals[tempoIndex][1], 1), 750,220+(tempoIndex*20));
|
|
andrew@2
|
441 }//end for interval index
|
|
andrew@2
|
442 }//end for tempo index
|
|
andrew@2
|
443
|
|
andrew@2
|
444 ofDrawBitmapString(ofToString(drumTracker.beatTimes.clickIndex), 750,20);
|
|
andrew@2
|
445
|
|
andrew@2
|
446 ofDrawBitmapString(ofToString(mouseBPM), 50,20);
|
|
andrew@2
|
447 ofDrawBitmapString(drumTracker.tempoDataString, 50, 100);
|
|
andrew@2
|
448
|
|
andrew@2
|
449 }//end draw tempo data
|
|
andrew@2
|
450
|
|
andrew@2
|
451
|
|
andrew@2
|
452 void testApp::drawTempoDistribution(){
|
|
andrew@2
|
453 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
454 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
455 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
456
|
|
andrew@2
|
457 maximum *= 1.1;
|
|
andrew@2
|
458
|
|
andrew@2
|
459 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
460
|
|
andrew@2
|
461
|
|
andrew@2
|
462
|
|
andrew@2
|
463 //draw prior in green
|
|
andrew@2
|
464 ofSetColor(0x888888);
|
|
andrew@2
|
465 for (int i = 1; i < ARRAY_SIZE; i+=2){
|
|
andrew@2
|
466 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight));
|
|
andrew@2
|
467 }
|
|
andrew@2
|
468
|
|
andrew@2
|
469
|
|
andrew@2
|
470 //draw posterior in dark
|
|
andrew@2
|
471 ofSetColor(0x000000);
|
|
andrew@2
|
472 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
473 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight));
|
|
andrew@2
|
474 }
|
|
andrew@2
|
475
|
|
andrew@2
|
476
|
|
andrew@2
|
477 //black line is the max probability
|
|
andrew@2
|
478 ofSetColor(0x000000);
|
|
andrew@2
|
479 ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0);
|
|
andrew@2
|
480
|
|
andrew@2
|
481 //blue is the current kick received
|
|
andrew@2
|
482 ofSetColor(0xAAAAAA);
|
|
andrew@2
|
483
|
|
andrew@2
|
484 int altIndex = 0;
|
|
andrew@2
|
485 for (altIndex = 0;altIndex< 16;altIndex++){
|
|
andrew@2
|
486
|
|
andrew@2
|
487 double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex];
|
|
andrew@2
|
488
|
|
andrew@2
|
489 if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){
|
|
andrew@2
|
490
|
|
andrew@2
|
491
|
|
andrew@2
|
492
|
|
andrew@2
|
493 //draw likelihood
|
|
andrew@2
|
494 //draw likelhood in blue
|
|
andrew@2
|
495 // //need to reset likelihood for this!
|
|
andrew@2
|
496 //XXX remove
|
|
andrew@2
|
497 double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex];
|
|
andrew@2
|
498 if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum)
|
|
andrew@2
|
499 {
|
|
andrew@2
|
500
|
|
andrew@2
|
501 ofLine(stepSize*(ARRAY_SIZE * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), screenHeight,
|
|
andrew@2
|
502 stepSize*(ARRAY_SIZE * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 0);
|
|
andrew@2
|
503
|
|
andrew@2
|
504 drumTracker.tempoDistribution.setGaussianLikelihood(ARRAY_SIZE * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
|
|
andrew@2
|
505 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
506 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight));
|
|
andrew@2
|
507 }
|
|
andrew@2
|
508 }
|
|
andrew@2
|
509
|
|
andrew@2
|
510 }
|
|
andrew@2
|
511
|
|
andrew@2
|
512 }//end for
|
|
andrew@2
|
513
|
|
andrew@2
|
514 if (bSmooth){
|
|
andrew@2
|
515 ofDisableSmoothing();
|
|
andrew@2
|
516 }
|
|
andrew@2
|
517
|
|
andrew@2
|
518 drawTempoInfo();
|
|
andrew@2
|
519
|
|
andrew@2
|
520 }
|
|
andrew@2
|
521
|
|
andrew@2
|
522
|
|
andrew@2
|
523 int testApp::xcoordinateFromTempoDataPoint(float f){
|
|
andrew@2
|
524 //f is the time
|
|
andrew@2
|
525
|
|
andrew@2
|
526 int xcoordinateForInterval = 0;
|
|
andrew@2
|
527 if (f >= drumTracker.tempoMinimum && f <= drumTracker.tempoMaximum)
|
|
andrew@2
|
528 xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum)*screenWidth/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum));
|
|
andrew@2
|
529 return xcoordinateForInterval;
|
|
andrew@2
|
530
|
|
andrew@2
|
531 }
|
|
andrew@2
|
532
|
|
andrew@2
|
533
|
|
andrew@2
|
534 int testApp::xcoordinateFromRestrictedTempoDataPoint(float f, const int& tmpMin, const int& tmpMax){
|
|
andrew@2
|
535
|
|
andrew@2
|
536
|
|
andrew@2
|
537 int xcoordinateForInterval = -1;
|
|
andrew@2
|
538 if (f >= drumTracker.tempoMinimum+tmpMin && f <= min(drumTracker.tempoMinimum+tmpMax,drumTracker.tempoMaximum))
|
|
andrew@2
|
539 xcoordinateForInterval = ((float)(f - drumTracker.tempoMinimum - tmpMin*arrayToMsecScaleFactor)*screenWidth/(float)((tmpMax - tmpMin)*arrayToMsecScaleFactor));
|
|
andrew@2
|
540 return xcoordinateForInterval;
|
|
andrew@2
|
541
|
|
andrew@2
|
542 }
|
|
andrew@2
|
543
|
|
andrew@2
|
544
|
|
andrew@2
|
545 void testApp::drawTempoInfo(){
|
|
andrew@2
|
546 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
547 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
548 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
549
|
|
andrew@2
|
550
|
|
andrew@2
|
551 ofSetColor(0x000000);
|
|
andrew@2
|
552 string testString;
|
|
andrew@2
|
553 testString = "max is ";
|
|
andrew@2
|
554 testString += ofToString(maximum);
|
|
andrew@2
|
555 ofDrawBitmapString(testString, 700,620);
|
|
andrew@2
|
556
|
|
andrew@2
|
557 ofDrawBitmapString(msg_string, 700,650);
|
|
andrew@2
|
558
|
|
andrew@2
|
559 ofDrawBitmapString(kickString, 700,670);
|
|
andrew@2
|
560
|
|
andrew@2
|
561 testString = "std dev : ";
|
|
andrew@2
|
562 testString += ofToString(drumTracker.tempoStdDev, 6);
|
|
andrew@2
|
563
|
|
andrew@2
|
564 testString += ", ";
|
|
andrew@2
|
565 testString += ofToString(drumTracker.accompanimentStarted);
|
|
andrew@2
|
566 ofDrawBitmapString(testString, 20, 120);
|
|
andrew@2
|
567
|
|
andrew@2
|
568 int tempoUpdateIndex;
|
|
andrew@2
|
569 for (tempoUpdateIndex = 0;tempoUpdateIndex<16;tempoUpdateIndex++){
|
|
andrew@2
|
570 // ofDrawBitmapString(tempoUpdateStrings[tempoUpdateIndex], 700, 200 + (20 * tempoUpdateIndex));
|
|
andrew@2
|
571 }
|
|
andrew@2
|
572
|
|
andrew@2
|
573 ofDrawBitmapString("Mouse located at tempo: ", 50,10);
|
|
andrew@2
|
574 ofDrawBitmapString(ofToString(mouseBPM, 1), 50,20);
|
|
andrew@2
|
575
|
|
andrew@2
|
576 ofDrawBitmapString("Current tempo: ", 50,40);
|
|
andrew@2
|
577 ofDrawBitmapString(ofToString(30000/drumTracker.beatTimes.tatum, 1), 50,50);
|
|
andrew@2
|
578
|
|
andrew@2
|
579 ofDrawBitmapString(drumTracker.tempoDataString, 50, 100);
|
|
andrew@2
|
580
|
|
andrew@2
|
581
|
|
andrew@2
|
582 for (int i = 1;i < 16; i++){
|
|
andrew@2
|
583 for (int altIndex = 0; altIndex < 16;altIndex++){
|
|
andrew@2
|
584 string newString;
|
|
andrew@2
|
585 newString = " :";
|
|
andrew@2
|
586 int recentIndex = (altIndex-i+16)%16;
|
|
andrew@2
|
587 if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){
|
|
andrew@2
|
588
|
|
andrew@2
|
589
|
|
andrew@2
|
590 int xcoordinateForInterval = xcoordinateFromTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex]);
|
|
andrew@2
|
591 float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2;
|
|
andrew@2
|
592
|
|
andrew@2
|
593 if (drumTracker.beatTimes.OnsetIsKick[altIndex])
|
|
andrew@2
|
594 ofSetColor(255*(8-beatInterval)/(float)8, 0, 255*beatInterval/(float)8);
|
|
andrew@2
|
595 else
|
|
andrew@2
|
596 ofSetColor(0, 255*(8-beatInterval)/(float)8, 255*beatInterval/(float)8);
|
|
andrew@2
|
597 //red kick, green snare
|
|
andrew@2
|
598
|
|
andrew@2
|
599 ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3);
|
|
andrew@2
|
600
|
|
andrew@2
|
601 newString += ofToString(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex],0);
|
|
andrew@2
|
602 newString += " (";
|
|
andrew@2
|
603 newString += ofToString(drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0);
|
|
andrew@2
|
604 newString += ")";
|
|
andrew@2
|
605
|
|
andrew@2
|
606 }
|
|
andrew@2
|
607 ofSetColor(0,0,0);
|
|
andrew@2
|
608 //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20));
|
|
andrew@2
|
609
|
|
andrew@2
|
610
|
|
andrew@2
|
611 }
|
|
andrew@2
|
612 }
|
|
andrew@2
|
613
|
|
andrew@2
|
614 }
|
|
andrew@2
|
615
|
|
andrew@2
|
616
|
|
andrew@2
|
617
|
|
andrew@2
|
618
|
|
andrew@2
|
619 void testApp::drawTempoDataPoints(const int& tmpMin, const int& tmpMax, const float& tmpStepSize){
|
|
andrew@2
|
620
|
|
andrew@2
|
621 for (int i = 1;i < 16; i++){
|
|
andrew@2
|
622 for (int altIndex = 0; altIndex < 16;altIndex++){
|
|
andrew@2
|
623 // string newString;
|
|
andrew@2
|
624 // newString = " :";
|
|
andrew@2
|
625
|
|
andrew@2
|
626 int recentIndex = (altIndex-i+16)%16;
|
|
andrew@2
|
627 if (drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex] > 0 && drumTracker.beatTimes.intervalUsed[altIndex][recentIndex]){
|
|
andrew@2
|
628
|
|
andrew@2
|
629 int xcoordinateForInterval = xcoordinateFromRestrictedTempoDataPoint(drumTracker.beatTimes.intervalDifferences[altIndex][recentIndex], tmpMin, tmpMax);
|
|
andrew@2
|
630 float beatInterval = (float) drumTracker.beatTimes.tatumMultiples[altIndex][recentIndex]/2;
|
|
andrew@2
|
631
|
|
andrew@2
|
632 if (drumTracker.beatTimes.OnsetIsKick[altIndex])
|
|
andrew@2
|
633 ofSetColor(255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7, 0);//100+155*(8-beatInterval)/(float)8
|
|
andrew@2
|
634 else
|
|
andrew@2
|
635 ofSetColor(0, 255*(7-beatInterval+1)/(float)7, 255*(beatInterval-1)/(float)7);//, 155*beatInterval/(float)8);
|
|
andrew@2
|
636 //red kick, green snare
|
|
andrew@2
|
637
|
|
andrew@2
|
638 ofCircle(xcoordinateForInterval, 200 + (altIndex * 20), 3);
|
|
andrew@2
|
639 ofDrawBitmapString(ofToString(beatInterval, 0), xcoordinateForInterval-2, 200 + (altIndex * 20) - 3);
|
|
andrew@2
|
640 /* newString += ofToString(beatTimes.intervalDifferences[altIndex][recentIndex],0);
|
|
andrew@2
|
641 newString += " (";
|
|
andrew@2
|
642 newString += ofToString(beatTimes.tatumMultiples[altIndex][recentIndex]/2, 0);
|
|
andrew@2
|
643 newString += ")";
|
|
andrew@2
|
644 */
|
|
andrew@2
|
645 }
|
|
andrew@2
|
646 ofSetColor(0,0,0);
|
|
andrew@2
|
647 //ofDrawBitmapString(newString, 200 + i*80, 200 + (altIndex * 20));
|
|
andrew@2
|
648
|
|
andrew@2
|
649
|
|
andrew@2
|
650 }
|
|
andrew@2
|
651 }
|
|
andrew@2
|
652
|
|
andrew@2
|
653 }
|
|
andrew@2
|
654
|
|
andrew@2
|
655
|
|
andrew@2
|
656 void testApp::drawRestrictedTempoDistribution(int tmpMin, int tmpMax){
|
|
andrew@2
|
657 //min and max are in the tempo array coordinates
|
|
andrew@2
|
658
|
|
andrew@2
|
659 tmpMin = max(tmpMin, 0);
|
|
andrew@2
|
660 tmpMax = min(tmpMax, ARRAY_SIZE-1);
|
|
andrew@2
|
661
|
|
andrew@2
|
662 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
663 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
664 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
665
|
|
andrew@2
|
666 maximum *= 1.1;
|
|
andrew@2
|
667
|
|
andrew@2
|
668 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
669 int tmpWidth = tmpMax - 1 - tmpMin;
|
|
andrew@2
|
670 float tmpStepSize = screenWidth / (float) tmpWidth;
|
|
andrew@2
|
671
|
|
andrew@2
|
672
|
|
andrew@2
|
673 //draw prior in green
|
|
andrew@2
|
674 ofSetColor(0x888888);
|
|
andrew@2
|
675 for (int i = 1; i < tmpWidth; i+=2){
|
|
andrew@2
|
676 ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i-1]*stepHeight), i * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.prior[tmpMin+i]*stepHeight));
|
|
andrew@2
|
677 }
|
|
andrew@2
|
678
|
|
andrew@2
|
679
|
|
andrew@2
|
680 //draw posterior in dark
|
|
andrew@2
|
681 ofSetColor(0x000000);
|
|
andrew@2
|
682 for (int i = 1; i < tmpWidth; i++){
|
|
andrew@2
|
683 ofLine((i-1) * tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.posterior[tmpMin+i]*stepHeight));
|
|
andrew@2
|
684 }
|
|
andrew@2
|
685
|
|
andrew@2
|
686
|
|
andrew@2
|
687 //black line is the max probability
|
|
andrew@2
|
688 ofSetColor(0x000000);
|
|
andrew@2
|
689 ofLine((drumTracker.tempoDistribution.integratedEstimate - tmpMin)* tmpStepSize, screenHeight, (drumTracker.tempoDistribution.integratedEstimate-tmpMin) *tmpStepSize, 0);
|
|
andrew@2
|
690
|
|
andrew@2
|
691 //blue is the current kick received
|
|
andrew@2
|
692 ofSetColor(0xAAAAAA);
|
|
andrew@2
|
693
|
|
andrew@2
|
694 int altIndex = 0;
|
|
andrew@2
|
695 for (altIndex = 0;altIndex< 16;altIndex++){
|
|
andrew@2
|
696 //iterate through all recent beat intervals
|
|
andrew@2
|
697
|
|
andrew@2
|
698 double tempoInterval = drumTracker.beatTimes.intervalDifferences[drumTracker.beatTimes.index][altIndex];
|
|
andrew@2
|
699
|
|
andrew@2
|
700 if (altIndex != drumTracker.beatTimes.index && tempoInterval > drumTracker.tempoMinimum && tempoInterval < drumTracker.tempoMaximum){
|
|
andrew@2
|
701
|
|
andrew@2
|
702 double timeInterval = drumTracker.beatTimes.beatTimes[drumTracker.beatTimes.index] - drumTracker.beatTimes.beatTimes[altIndex];
|
|
andrew@2
|
703
|
|
andrew@2
|
704 if (timeInterval > 2*drumTracker.tempoMinimum && timeInterval < 2*drumTracker.tempoMaximum){
|
|
andrew@2
|
705 //i.e. within the beat range only
|
|
andrew@2
|
706 //so we only draw the likelihood realtime for happening beat intervals
|
|
andrew@2
|
707 //in fact much more is going on than this but harder to visualise
|
|
andrew@2
|
708
|
|
andrew@2
|
709 float indexOfNewLocation = ARRAY_SIZE*(tempoInterval-drumTracker.tempoMinimum)/(float)(drumTracker.tempoMaximum - drumTracker.tempoMinimum);
|
|
andrew@2
|
710
|
|
andrew@2
|
711
|
|
andrew@2
|
712 if (indexOfNewLocation >= tmpMin){
|
|
andrew@2
|
713 ofLine(tmpStepSize * (indexOfNewLocation-tmpMin), screenHeight, tmpStepSize * (indexOfNewLocation-tmpMin) , 0);
|
|
andrew@2
|
714 }
|
|
andrew@2
|
715
|
|
andrew@2
|
716
|
|
andrew@2
|
717 drumTracker.tempoDistribution.setGaussianLikelihood(ARRAY_SIZE * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
|
|
andrew@2
|
718 //setting the tempo distribution likeihood just for visualisation purposes
|
|
andrew@2
|
719 for (int i = 1; i < tmpWidth; i++){
|
|
andrew@2
|
720 ofLine((i-1)*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin-1]*stepHeight), i*tmpStepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i+tmpMin]*stepHeight));
|
|
andrew@2
|
721
|
|
andrew@2
|
722 }
|
|
andrew@2
|
723 }
|
|
andrew@2
|
724
|
|
andrew@2
|
725 }
|
|
andrew@2
|
726
|
|
andrew@2
|
727 }//end for
|
|
andrew@2
|
728
|
|
andrew@2
|
729 if (bSmooth){
|
|
andrew@2
|
730 ofDisableSmoothing();
|
|
andrew@2
|
731 }
|
|
andrew@2
|
732
|
|
andrew@2
|
733
|
|
andrew@2
|
734 drawTempoDataPoints(tmpMin, tmpMax, tmpStepSize);
|
|
andrew@2
|
735
|
|
andrew@2
|
736 // lines for background
|
|
andrew@2
|
737 for (int i = tmpMin-(tmpMin%20);i < tmpMax; i+=20){
|
|
andrew@2
|
738 ofSetColor(0,0,200,100);
|
|
andrew@2
|
739 ofLine(tmpStepSize * (i-tmpMin), screenHeight, tmpStepSize * (i-tmpMin) , 0);
|
|
andrew@2
|
740 string tmpTempoString = ofToString(drumTracker.tempoMinimum + i*arrayToMsecScaleFactor, 0);
|
|
andrew@2
|
741 ofDrawBitmapString(tmpTempoString, tmpStepSize * (i-tmpMin) , 20);
|
|
andrew@2
|
742 }
|
|
andrew@2
|
743
|
|
andrew@2
|
744 string currentTatumString = "Beat Period : ";
|
|
andrew@2
|
745 currentTatumString += ofToString(drumTracker.beatTimes.tatum, 1);
|
|
andrew@2
|
746 currentTatumString += " MaxIndex : ";
|
|
andrew@2
|
747 currentTatumString += ofToString(drumTracker.tempoDistribution.integratedEstimate, 1);
|
|
andrew@2
|
748
|
|
andrew@2
|
749 ofDrawBitmapString(currentTatumString, 20, 40);
|
|
andrew@2
|
750 //drawTempoInfo();
|
|
andrew@2
|
751
|
|
andrew@2
|
752 }
|
|
andrew@2
|
753
|
|
andrew@2
|
754
|
|
andrew@2
|
755
|
|
andrew@2
|
756
|
|
andrew@2
|
757
|
|
andrew@2
|
758
|
|
andrew@2
|
759
|
|
andrew@2
|
760
|
|
andrew@2
|
761
|
|
andrew@2
|
762
|
|
andrew@2
|
763
|
|
andrew@2
|
764 void testApp::drawBeatMap(){
|
|
andrew@2
|
765 int x,y;
|
|
andrew@2
|
766
|
|
andrew@2
|
767 for (x=0;x < 6;x++){
|
|
andrew@2
|
768 for (y=0;y<8;y++){
|
|
andrew@2
|
769 int cell = x+(y*6);
|
|
andrew@2
|
770 if (cell == drumTracker.beatTimes.beatSegment){
|
|
andrew@2
|
771 if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick
|
|
andrew@2
|
772 ofSetColor(drumTracker.beatTimes.beatMap[cell]*255, 0, 0);
|
|
andrew@2
|
773
|
|
andrew@2
|
774 if (drumTracker.beatTimes.beatMap[cell] == 2)//for kick
|
|
andrew@2
|
775 ofSetColor(0, drumTracker.beatTimes.beatMap[cell]*255, 100);
|
|
andrew@2
|
776
|
|
andrew@2
|
777 }
|
|
andrew@2
|
778 else{
|
|
andrew@2
|
779 if (drumTracker.beatTimes.beatMap[cell] == 1)//for kick
|
|
andrew@2
|
780 ofSetColor(drumTracker.beatTimes.beatMap[cell]*155, 0, 0);
|
|
andrew@2
|
781 else //for snare
|
|
andrew@2
|
782 ofSetColor(0,drumTracker.beatTimes.beatMap[cell]*155, 0);//beatTimes.beatMap[cell]*155);
|
|
andrew@2
|
783
|
|
andrew@2
|
784 }
|
|
andrew@2
|
785 ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8);
|
|
andrew@2
|
786
|
|
andrew@2
|
787 ofSetColor(255,0,0);
|
|
andrew@2
|
788 ofDrawBitmapString(ofToString(x+(y*6)), screenWidth*x/6, screenHeight*y/8);
|
|
andrew@2
|
789
|
|
andrew@2
|
790 if (drumTracker.beatTimes.beatMap[cell] == 1){
|
|
andrew@2
|
791 ofSetColor(0,255,255);//
|
|
andrew@2
|
792 ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) );
|
|
andrew@2
|
793 }
|
|
andrew@2
|
794 if (drumTracker.beatTimes.beatMap[cell] == 2){
|
|
andrew@2
|
795 ofSetColor(0,0,100);//
|
|
andrew@2
|
796 ofDrawBitmapString(ofToString(drumTracker.beatTimes.beatMapTimeDifferences[cell], 2), (screenWidth*(x+0.5)/6) , (screenHeight*(y+0.5)/8) );
|
|
andrew@2
|
797 }
|
|
andrew@2
|
798
|
|
andrew@2
|
799
|
|
andrew@2
|
800 }
|
|
andrew@2
|
801 }
|
|
andrew@2
|
802
|
|
andrew@2
|
803 }
|
|
andrew@2
|
804
|
|
andrew@2
|
805
|
|
andrew@2
|
806
|
|
andrew@2
|
807
|
|
andrew@2
|
808 void testApp::drawBeatProbabilityDistribution(){
|
|
andrew@2
|
809 int x,y;
|
|
andrew@2
|
810
|
|
andrew@2
|
811 for (x=0;x < 6;x++){
|
|
andrew@2
|
812 for (y=0;y<4;y++){
|
|
andrew@2
|
813 int cell = x+(y*6);
|
|
andrew@2
|
814 ofSetColor(drumTracker.beatTimes.beatProbabilityDistribution[y][x][0]*255, 0, 0);
|
|
andrew@2
|
815 ofRect(screenWidth*x/6, screenHeight*y/8, screenWidth/6, screenHeight/8);
|
|
andrew@2
|
816 }
|
|
andrew@2
|
817 }
|
|
andrew@2
|
818 for (x=0;x < 6;x++){
|
|
andrew@2
|
819 for (y=0;y<4;y++){
|
|
andrew@2
|
820 int cell = x+(y*6);
|
|
andrew@2
|
821 ofSetColor(0, drumTracker.beatTimes.beatProbabilityDistribution[y][x][1]*255, 0);
|
|
andrew@2
|
822 ofRect(screenWidth*x/6, screenHeight*(y+4)/8, screenWidth/6, screenHeight/8);
|
|
andrew@2
|
823 }
|
|
andrew@2
|
824 }
|
|
andrew@2
|
825
|
|
andrew@2
|
826 }
|
|
andrew@2
|
827
|
|
andrew@2
|
828
|
|
andrew@2
|
829 void testApp::drawNormalisedLikelihood(){
|
|
andrew@2
|
830 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
831 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
832 //maximum = max(maximum, beatDistribution.getMaximum(&beatDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
833 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
834
|
|
andrew@2
|
835 if (!hidePriorMode){
|
|
andrew@2
|
836 //draw likelhood in blue
|
|
andrew@2
|
837
|
|
andrew@2
|
838 ofSetColor(0x0000FF);
|
|
andrew@2
|
839 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
840 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
|
|
andrew@2
|
841 }
|
|
andrew@2
|
842
|
|
andrew@2
|
843 //draw prior in green
|
|
andrew@2
|
844 ofSetColor(0x00AA00);
|
|
andrew@2
|
845 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
846 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
|
|
andrew@2
|
847 }
|
|
andrew@2
|
848 }//end hide prior mode
|
|
andrew@2
|
849
|
|
andrew@2
|
850
|
|
andrew@2
|
851
|
|
andrew@2
|
852 }
|
|
andrew@2
|
853
|
|
andrew@2
|
854
|
|
andrew@2
|
855
|
|
andrew@2
|
856 void testApp::drawPosterior(){
|
|
andrew@2
|
857 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], ARRAY_SIZE);
|
|
andrew@2
|
858
|
|
andrew@2
|
859 if (drumTracker.posteriorMaximum < maximum){
|
|
andrew@2
|
860 drumTracker.posteriorMaximum = 1.2*maximum;
|
|
andrew@2
|
861 }
|
|
andrew@2
|
862
|
|
andrew@2
|
863 float stepHeight = screenHeight/drumTracker.posteriorMaximum;
|
|
andrew@2
|
864 ofSetColor(0xFF00FF);
|
|
andrew@2
|
865 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
866 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
|
|
andrew@2
|
867 }
|
|
andrew@2
|
868
|
|
andrew@2
|
869
|
|
andrew@2
|
870 //yellow is the middle
|
|
andrew@2
|
871 ofSetColor(0xFFFF00);
|
|
andrew@2
|
872 ofLine(ARRAY_SIZE*stepSize/2, screenHeight, ARRAY_SIZE*stepSize/2, 0);
|
|
andrew@2
|
873
|
|
andrew@2
|
874
|
|
andrew@2
|
875
|
|
andrew@2
|
876 //blue is the current kick received
|
|
andrew@2
|
877 ofSetColor(0x0000FF);
|
|
andrew@2
|
878 ofLine(stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), screenHeight,stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), 0);
|
|
andrew@2
|
879
|
|
andrew@2
|
880 //purple line is the integrated max probability
|
|
andrew@2
|
881 int integratedBeatEstimateDrawPoint = round(drumTracker.beatDistribution.integratedEstimate*stepSize) ;
|
|
andrew@2
|
882 ofSetColor(0xFF22FF);
|
|
andrew@2
|
883 ofLine(integratedBeatEstimateDrawPoint, screenHeight, integratedBeatEstimateDrawPoint, 0);
|
|
andrew@2
|
884
|
|
andrew@2
|
885 string testString = "maximum: ";
|
|
andrew@2
|
886 testString += ofToString(drumTracker.posteriorMaximum, 2);
|
|
andrew@2
|
887 ofDrawBitmapString(testString, 100,120);
|
|
andrew@2
|
888
|
|
andrew@2
|
889
|
|
andrew@2
|
890 }
|
|
andrew@2
|
891
|
|
andrew@2
|
892
|
|
andrew@2
|
893
|
|
andrew@2
|
894
|
|
andrew@2
|
895
|
|
andrew@2
|
896 void testApp::drawBayesianDistribution(){
|
|
andrew@2
|
897 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
898 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
899 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
900 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
901
|
|
andrew@2
|
902 if (!hidePriorMode){
|
|
andrew@2
|
903 //draw likelhood in blue
|
|
andrew@2
|
904 if (drumTracker.onsetType == "kick")
|
|
andrew@2
|
905 ofSetColor(0xff0000);//red : kick
|
|
andrew@2
|
906 else
|
|
andrew@2
|
907 ofSetColor(0x00FF00);//green : snare
|
|
andrew@2
|
908
|
|
andrew@2
|
909 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
910 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
|
|
andrew@2
|
911 }
|
|
andrew@2
|
912
|
|
andrew@2
|
913 //;line where the current kick is received
|
|
andrew@2
|
914 ofLine(stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), screenHeight,stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), 0);
|
|
andrew@2
|
915
|
|
andrew@2
|
916
|
|
andrew@2
|
917 //draw prior in aqua blue
|
|
andrew@2
|
918 ofSetColor(0x00AAAA);
|
|
andrew@2
|
919 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
920 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
|
|
andrew@2
|
921 }
|
|
andrew@2
|
922 }//end hide prior mode
|
|
andrew@2
|
923
|
|
andrew@2
|
924 //draw posterior in red
|
|
andrew@2
|
925 ofSetColor(0x0000FF);
|
|
andrew@2
|
926 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
927 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
|
|
andrew@2
|
928 }
|
|
andrew@2
|
929
|
|
andrew@2
|
930 //draw the previous updated posteriror in purple
|
|
andrew@2
|
931 /* ofSetColor(0xFF22FF);
|
|
andrew@2
|
932 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
933 ofLine((i-1)*stepSize, screenHeight - (tmpArray[i-1]*stepHeight), i*stepSize, screenHeight - (tmpArray[i]*stepHeight));
|
|
andrew@2
|
934 }
|
|
andrew@2
|
935 */
|
|
andrew@2
|
936
|
|
andrew@2
|
937 //yellow is the middle
|
|
andrew@2
|
938 ofSetColor(0xFFFF00);
|
|
andrew@2
|
939 ofLine(ARRAY_SIZE*stepSize/2, screenHeight, ARRAY_SIZE*stepSize/2, 0);
|
|
andrew@2
|
940
|
|
andrew@2
|
941 //black line is the max probability
|
|
andrew@2
|
942 ofSetColor(0x000000);
|
|
andrew@2
|
943 ofLine(drumTracker.beatDistribution.maximumIndex*stepSize, screenHeight, drumTracker.beatDistribution.maximumIndex*stepSize, 0);
|
|
andrew@2
|
944
|
|
andrew@2
|
945
|
|
andrew@2
|
946 //purple line is the integrated max probability
|
|
andrew@2
|
947 int integratedBeatEstimate = drumTracker.beatDistribution.integratedEstimate ;
|
|
andrew@2
|
948 ofSetColor(0x2222FF);
|
|
andrew@2
|
949 ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0);
|
|
andrew@2
|
950
|
|
andrew@2
|
951
|
|
andrew@2
|
952 if (bSmooth){
|
|
andrew@2
|
953 ofDisableSmoothing();
|
|
andrew@2
|
954 }
|
|
andrew@2
|
955
|
|
andrew@2
|
956 printBayesianData();
|
|
andrew@2
|
957 }
|
|
andrew@2
|
958
|
|
andrew@2
|
959 void testApp::printBayesianData(){
|
|
andrew@2
|
960 //not optimised!!! XXX
|
|
andrew@2
|
961 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
962 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
963 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
964
|
|
andrew@2
|
965 ofSetColor(0x000000);
|
|
andrew@2
|
966 string testString;
|
|
andrew@2
|
967 testString = "max2 is ";
|
|
andrew@2
|
968 testString += ofToString(maximum, 3);
|
|
andrew@2
|
969 testString += " :: ";
|
|
andrew@2
|
970
|
|
andrew@2
|
971 testString = "correction of ";
|
|
andrew@2
|
972 testString += ofToString(drumTracker.beatCorrection);
|
|
andrew@2
|
973 testString += " corr by :";
|
|
andrew@2
|
974 testString += ofToString(drumTracker.correctBeatBy);
|
|
andrew@2
|
975
|
|
andrew@2
|
976 //ofDrawBitmapString(testString, 100,120);
|
|
andrew@2
|
977
|
|
andrew@2
|
978 testString = "MaxPhase ";
|
|
andrew@2
|
979 testString += ofToString(drumTracker.maxPhase);
|
|
andrew@2
|
980 // ofDrawBitmapString(testString, 100,140);
|
|
andrew@2
|
981
|
|
andrew@2
|
982
|
|
andrew@2
|
983 testString = "Likelihood noise ";
|
|
andrew@2
|
984 testString += ofToString(drumTracker.beatDistribution.likelihoodNoise, 2);
|
|
andrew@2
|
985 //ofDrawBitmapString(testString, 100,160);
|
|
andrew@2
|
986
|
|
andrew@2
|
987 // ofDrawBitmapString(msg_string, 100,140);
|
|
andrew@2
|
988
|
|
andrew@2
|
989 // ofDrawBitmapString(kickString, 100,180);
|
|
andrew@2
|
990
|
|
andrew@2
|
991 /* debugString = "Min Debug = ";
|
|
andrew@2
|
992 debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.minTempoIndex);
|
|
andrew@2
|
993 debugString += " Max Debug = ";
|
|
andrew@2
|
994 debugString += ofToString(drumTracker.tempoDistribution.maximumIndex + drumTracker.maxTempoIndex);
|
|
andrew@2
|
995 */
|
|
andrew@2
|
996 //ofDrawBitmapString(debugString, 300,370);
|
|
andrew@2
|
997
|
|
andrew@2
|
998 debugString = "CLICK INDEX = ";
|
|
andrew@2
|
999 debugString += ofToString(drumTracker.beatTimes.clickIndex);
|
|
andrew@2
|
1000 //ofDrawBitmapString(debugString, 100, 20);
|
|
andrew@2
|
1001
|
|
andrew@2
|
1002 debugString = "STD DEV = ";
|
|
andrew@2
|
1003 debugString += ofToString(drumTracker.beatDistribution.standardDeviation, 2);
|
|
andrew@2
|
1004 // ofDrawBitmapString(debugString, 100, 40);
|
|
andrew@2
|
1005
|
|
andrew@2
|
1006
|
|
andrew@2
|
1007
|
|
andrew@2
|
1008 debugString = "interval ";
|
|
andrew@2
|
1009 debugString += ofToString(drumTracker.debugArray[2], 2);
|
|
andrew@2
|
1010 debugString += " time int = ";
|
|
andrew@2
|
1011 debugString += ofToString(drumTracker.debugArray[1], 2);
|
|
andrew@2
|
1012 debugString += " Beat max = ";
|
|
andrew@2
|
1013 debugString += ofToString(drumTracker.debugArray[0 ], 2);
|
|
andrew@2
|
1014 debugString += " Tempo max = ";
|
|
andrew@2
|
1015 debugString += ofToString(drumTracker.debugArray[3 ], 2);
|
|
andrew@2
|
1016 // ofDrawBitmapString(debugString, 300,570);
|
|
andrew@2
|
1017
|
|
andrew@2
|
1018 debugString = " last = ";
|
|
andrew@2
|
1019 debugString += ofToString(drumTracker.beatTimes.lastBeatTime, 2);
|
|
andrew@2
|
1020 // ofDrawBitmapString(debugString, 300,470);
|
|
andrew@2
|
1021
|
|
andrew@2
|
1022
|
|
andrew@2
|
1023 string closestClickString = "Closest Click ";
|
|
andrew@2
|
1024 closestClickString += ofToString(drumTracker.beatTimes.closestClickIndexToBeat[drumTracker.beatTimes.index]);
|
|
andrew@2
|
1025 closestClickString += " beat seg ";
|
|
andrew@2
|
1026 closestClickString += ofToString(drumTracker.beatTimes.beatSegment%12);
|
|
andrew@2
|
1027 closestClickString += " lastCindex";
|
|
andrew@2
|
1028 closestClickString += ofToString(drumTracker.beatTimes.lastClickIndex);
|
|
andrew@2
|
1029 closestClickString += " TD ";
|
|
andrew@2
|
1030 closestClickString += ofToString(drumTracker.beatTimes.timeDifference);
|
|
andrew@2
|
1031
|
|
andrew@2
|
1032 // ofDrawBitmapString(closestClickString, 100,100);
|
|
andrew@2
|
1033
|
|
andrew@2
|
1034 // ofDrawBitmapString(timeString, 100,60);
|
|
andrew@2
|
1035 }
|
|
andrew@2
|
1036
|
|
andrew@2
|
1037
|
|
andrew@2
|
1038
|
|
andrew@2
|
1039 void testApp::drawGreyscaleBayesianDistribution(){
|
|
andrew@2
|
1040 ofSetColor(255,255,255);
|
|
andrew@2
|
1041 ofRect(0,0,screenWidth, screenHeight);
|
|
andrew@2
|
1042
|
|
andrew@2
|
1043 float maximum = drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
1044 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
1045 maximum = max(maximum, drumTracker.beatDistribution.getMaximum(&drumTracker.beatDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
1046 maximum *= 1.1;
|
|
andrew@2
|
1047 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
1048
|
|
andrew@2
|
1049 if (!hidePriorMode){
|
|
andrew@2
|
1050 //draw likelhood in blue
|
|
andrew@2
|
1051 ofSetColor(0x555555);
|
|
andrew@2
|
1052 for (int i = 1; i < ARRAY_SIZE; i+=2){
|
|
andrew@2
|
1053 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.likelihood[i]*stepHeight));
|
|
andrew@2
|
1054 }
|
|
andrew@2
|
1055
|
|
andrew@2
|
1056 //draw prior in green
|
|
andrew@2
|
1057 ofSetColor(0xAAAAAA);
|
|
andrew@2
|
1058 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
1059 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.prior[i]*stepHeight));
|
|
andrew@2
|
1060 }
|
|
andrew@2
|
1061 }//end hide prior mode
|
|
andrew@2
|
1062
|
|
andrew@2
|
1063 //draw posterior in dark grey
|
|
andrew@2
|
1064 ofSetColor(0x222222);
|
|
andrew@2
|
1065 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
1066 ofLine((i-1)*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.beatDistribution.posterior[i]*stepHeight));
|
|
andrew@2
|
1067 }
|
|
andrew@2
|
1068
|
|
andrew@2
|
1069 /*
|
|
andrew@2
|
1070 //dotted the middle
|
|
andrew@2
|
1071 ofSetColor(0x555555);
|
|
andrew@2
|
1072 for (int i = 1; i < screenHeight; i+=4){
|
|
andrew@2
|
1073 ofLine(ARRAY_SIZE*stepSize/2, i, ARRAY_SIZE*stepSize/2, i-2);
|
|
andrew@2
|
1074 }
|
|
andrew@2
|
1075 */
|
|
andrew@2
|
1076
|
|
andrew@2
|
1077 //purple line is the integrated max probability
|
|
andrew@2
|
1078 // int integratedBeatEstimate = beatDistribution.integratedEstimate ;
|
|
andrew@2
|
1079 // ofSetColor(0x000000);
|
|
andrew@2
|
1080 // ofLine(integratedBeatEstimate *stepSize, screenHeight, integratedBeatEstimate *stepSize, 0);
|
|
andrew@2
|
1081
|
|
andrew@2
|
1082 //purple line is the integrated max probability
|
|
andrew@2
|
1083 float tmpIntegratedBeatEstimate = drumTracker.beatDistribution.getIntegratedEstimateIndex();
|
|
andrew@2
|
1084 ofSetColor(0x000000);
|
|
andrew@2
|
1085 int drawLinePoint = round(tmpIntegratedBeatEstimate *stepSize);
|
|
andrew@2
|
1086 ofLine(drawLinePoint, screenHeight, drawLinePoint, 0);
|
|
andrew@2
|
1087
|
|
andrew@2
|
1088 //blue is the current kick received
|
|
andrew@2
|
1089 ofSetColor(0x555555);
|
|
andrew@2
|
1090 for (int i = 1; i < screenHeight; i+=40){
|
|
andrew@2
|
1091 ofLine(stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), i,stepSize*((ARRAY_SIZE/2) + (ARRAY_SIZE*drumTracker.kickError)), i-20);
|
|
andrew@2
|
1092 }
|
|
andrew@2
|
1093
|
|
andrew@2
|
1094
|
|
andrew@2
|
1095 }
|
|
andrew@2
|
1096
|
|
andrew@2
|
1097
|
|
andrew@2
|
1098
|
|
andrew@2
|
1099
|
|
andrew@2
|
1100 void testApp::drawGreyscaleTempoDistribution(double tempoInterval){
|
|
andrew@2
|
1101 ofSetColor(255,255,255);
|
|
andrew@2
|
1102 ofRect(0,0,screenWidth, screenHeight);
|
|
andrew@2
|
1103
|
|
andrew@2
|
1104 float maximum = drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.likelihood[0], ARRAY_SIZE);
|
|
andrew@2
|
1105 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.prior[0], ARRAY_SIZE));
|
|
andrew@2
|
1106 maximum = max(maximum, drumTracker.tempoDistribution.getMaximum(&drumTracker.tempoDistribution.posterior[0], ARRAY_SIZE));
|
|
andrew@2
|
1107
|
|
andrew@2
|
1108 maximum *= 1.1;
|
|
andrew@2
|
1109
|
|
andrew@2
|
1110 float stepHeight = screenHeight/maximum;
|
|
andrew@2
|
1111
|
|
andrew@2
|
1112 //draw prior in green
|
|
andrew@2
|
1113 ofSetColor(0x777777);
|
|
andrew@2
|
1114 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
1115 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.prior[i]*stepHeight));
|
|
andrew@2
|
1116 }
|
|
andrew@2
|
1117
|
|
andrew@2
|
1118
|
|
andrew@2
|
1119 //draw posterior in dark
|
|
andrew@2
|
1120 ofSetColor(0x000000);
|
|
andrew@2
|
1121 for (int i = 1; i < ARRAY_SIZE; i++){
|
|
andrew@2
|
1122 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.posterior[i]*stepHeight));
|
|
andrew@2
|
1123 }
|
|
andrew@2
|
1124
|
|
andrew@2
|
1125
|
|
andrew@2
|
1126 //black line is the max probability
|
|
andrew@2
|
1127 ofSetColor(0xFF0000);
|
|
andrew@2
|
1128 ofLine(drumTracker.tempoDistribution.integratedEstimate *stepSize, screenHeight, drumTracker.tempoDistribution.integratedEstimate *stepSize, 0);
|
|
andrew@2
|
1129
|
|
andrew@2
|
1130 //blue is the current kick received
|
|
andrew@2
|
1131 ofSetColor(0xAAAAAA);
|
|
andrew@2
|
1132
|
|
andrew@2
|
1133
|
|
andrew@2
|
1134
|
|
andrew@2
|
1135
|
|
andrew@2
|
1136 for (int k =1;k < screenHeight/12;k+=2){
|
|
andrew@2
|
1137 ofLine(stepSize*(ARRAY_SIZE * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)), 12*k,
|
|
andrew@2
|
1138 stepSize*(ARRAY_SIZE * (tempoInterval-drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum)) , 12*(k-1));
|
|
andrew@2
|
1139 }
|
|
andrew@2
|
1140
|
|
andrew@2
|
1141 drumTracker.tempoDistribution.setGaussianLikelihood(ARRAY_SIZE * (tempoInterval - drumTracker.tempoMinimum)/(drumTracker.tempoMaximum - drumTracker.tempoMinimum), drumTracker.tempoDistribution.likelihoodStdDev);
|
|
andrew@2
|
1142 for (int i = 1; i < ARRAY_SIZE; i+=2){
|
|
andrew@2
|
1143 //dotted line likelihood fn
|
|
andrew@2
|
1144 ofLine((i-1)*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i-1]*stepHeight), i*stepSize, screenHeight - (drumTracker.tempoDistribution.likelihood[i]*stepHeight));
|
|
andrew@2
|
1145 }
|
|
andrew@2
|
1146
|
|
andrew@2
|
1147
|
|
andrew@2
|
1148
|
|
andrew@2
|
1149
|
|
andrew@2
|
1150 if (bSmooth){
|
|
andrew@2
|
1151 ofDisableSmoothing();
|
|
andrew@2
|
1152 }
|
|
andrew@2
|
1153
|
|
andrew@2
|
1154 }
|
|
andrew@2
|
1155
|
|
andrew@2
|
1156
|
|
andrew@2
|
1157
|
|
andrew@2
|
1158
|
|
andrew@2
|
1159 //--------------------------------------------------------------
|
|
andrew@2
|
1160 void testApp::keyPressed (int key){
|
|
andrew@2
|
1161 if (key == 's'){
|
|
andrew@2
|
1162 bSmooth = !bSmooth;
|
|
andrew@2
|
1163 }
|
|
andrew@2
|
1164
|
|
andrew@2
|
1165 if (key == 'x'){
|
|
andrew@2
|
1166 printInterval = !printInterval;
|
|
andrew@2
|
1167 }
|
|
andrew@2
|
1168
|
|
andrew@2
|
1169
|
|
andrew@2
|
1170 if (key == 'y'){
|
|
andrew@2
|
1171 drawData = !drawData;
|
|
andrew@2
|
1172 }
|
|
andrew@2
|
1173
|
|
andrew@2
|
1174 if (key == 'f'){
|
|
andrew@2
|
1175 ofToggleFullscreen();
|
|
andrew@2
|
1176 }
|
|
andrew@2
|
1177
|
|
andrew@2
|
1178 if (key == 'h' || key == 'H'){
|
|
andrew@2
|
1179 hidePriorMode = !hidePriorMode;//drawData;
|
|
andrew@2
|
1180 }
|
|
andrew@2
|
1181
|
|
andrew@2
|
1182
|
|
andrew@2
|
1183
|
|
andrew@2
|
1184 if ( key =='a' || key == 'A' )
|
|
andrew@2
|
1185 {
|
|
andrew@2
|
1186
|
|
andrew@2
|
1187 }
|
|
andrew@2
|
1188
|
|
andrew@2
|
1189 if (key == ' '){
|
|
andrew@2
|
1190 drumTracker.paused = !drumTracker.paused;
|
|
andrew@2
|
1191 }
|
|
andrew@2
|
1192
|
|
andrew@2
|
1193 if (key == OF_KEY_RIGHT){
|
|
andrew@2
|
1194 screenToDraw++;
|
|
andrew@2
|
1195 screenToDraw = screenToDraw % NUMBER_OF_SCREENS;
|
|
andrew@2
|
1196 }
|
|
andrew@2
|
1197 if (key == OF_KEY_LEFT){
|
|
andrew@2
|
1198 screenToDraw += NUMBER_OF_SCREENS - 1;
|
|
andrew@2
|
1199 screenToDraw = screenToDraw % NUMBER_OF_SCREENS;
|
|
andrew@2
|
1200 }
|
|
andrew@2
|
1201
|
|
andrew@2
|
1202 if (key == ']')
|
|
andrew@2
|
1203 drumTracker.beatDistribution.translateDistribution(ARRAY_SIZE / 4);
|
|
andrew@2
|
1204
|
|
andrew@2
|
1205 if (key == '[')
|
|
andrew@2
|
1206 drumTracker.beatDistribution.translateDistribution(-1*ARRAY_SIZE / 4);
|
|
andrew@2
|
1207
|
|
andrew@2
|
1208 if (key == 'x'){
|
|
andrew@2
|
1209 bSnapshot = true;
|
|
andrew@2
|
1210 }
|
|
andrew@2
|
1211
|
|
andrew@2
|
1212 if (key == 'q')
|
|
andrew@2
|
1213 drumTracker.adaptiveStandardDeviationMode = !drumTracker.adaptiveStandardDeviationMode;
|
|
andrew@2
|
1214
|
|
andrew@2
|
1215 }
|
|
andrew@2
|
1216
|
|
andrew@2
|
1217 /*
|
|
andrew@2
|
1218 void testApp::sendMaxTempo(){
|
|
andrew@2
|
1219 ofxOscMessage m;
|
|
andrew@2
|
1220 m.setAddress( "/tempo" );
|
|
andrew@2
|
1221
|
|
andrew@2
|
1222 //maxTempo = tempoDistribution.maximumIndex * (tempoMaximum - tempoMinimum) / ARRAY_SIZE;
|
|
andrew@2
|
1223 //would be introduced new in bayesian8
|
|
andrew@2
|
1224 maxTempo = drumTracker.tempoDistribution.getIntegratedEstimateIndex() * (tempoMaximum - tempoMinimum) / ARRAY_SIZE;
|
|
andrew@2
|
1225 maxTempo += tempoMinimum;
|
|
andrew@2
|
1226
|
|
andrew@2
|
1227
|
|
andrew@2
|
1228 m.addFloatArg( maxTempo );
|
|
andrew@2
|
1229 sender.sendMessage( m );
|
|
andrew@2
|
1230
|
|
andrew@2
|
1231 printf("max tempo %f\n", maxTempo);
|
|
andrew@2
|
1232
|
|
andrew@2
|
1233 }
|
|
andrew@2
|
1234
|
|
andrew@2
|
1235 void testApp::sendMaxPhase(){
|
|
andrew@2
|
1236
|
|
andrew@2
|
1237
|
|
andrew@2
|
1238 // maxPhase = (beatDistribution.maximumIndex - (ARRAY_SIZE/2)) / ARRAY_SIZE;
|
|
andrew@2
|
1239 maxPhase = (drumTracker.beatDistribution.getIntegratedEstimateIndex() - (ARRAY_SIZE/2)) / ARRAY_SIZE;
|
|
andrew@2
|
1240 printf("\nphase index %f :: %i\n", drumTracker.beatDistribution.integratedEstimate , maxPhase);
|
|
andrew@2
|
1241 ofxOscMessage m;
|
|
andrew@2
|
1242 m.setAddress( "/phase" );
|
|
andrew@2
|
1243 m.addFloatArg( maxPhase );
|
|
andrew@2
|
1244 sender.sendMessage( m );
|
|
andrew@2
|
1245
|
|
andrew@2
|
1246 //beatCorrection = maxPhase * beatTimes.tatum / 4;
|
|
andrew@2
|
1247 }
|
|
andrew@2
|
1248 */
|
|
andrew@2
|
1249 //--------------------------------------------------------------
|
|
andrew@2
|
1250 void testApp::keyReleased (int key){
|
|
andrew@2
|
1251
|
|
andrew@2
|
1252 }
|
|
andrew@2
|
1253
|
|
andrew@2
|
1254 //--------------------------------------------------------------
|
|
andrew@2
|
1255 void testApp::mouseMoved(int x, int y ){
|
|
andrew@2
|
1256
|
|
andrew@2
|
1257 mouseBPM = convertToBPM(drumTracker.tempoMinimum+ ((x * (drumTracker.tempoMaximum - drumTracker.tempoMinimum) ) / ofGetWidth() )) ;
|
|
andrew@2
|
1258 }
|
|
andrew@2
|
1259
|
|
andrew@2
|
1260 //--------------------------------------------------------------
|
|
andrew@2
|
1261 void testApp::mouseDragged(int x, int y, int button){
|
|
andrew@2
|
1262 }
|
|
andrew@2
|
1263
|
|
andrew@2
|
1264 //--------------------------------------------------------------
|
|
andrew@2
|
1265 void testApp::mousePressed(int x, int y, int button){
|
|
andrew@2
|
1266 }
|
|
andrew@2
|
1267
|
|
andrew@2
|
1268
|
|
andrew@2
|
1269 //--------------------------------------------------------------
|
|
andrew@2
|
1270 void testApp::mouseReleased(int x, int y, int button){
|
|
andrew@2
|
1271
|
|
andrew@2
|
1272 }
|
|
andrew@2
|
1273
|
|
andrew@2
|
1274 //--------------------------------------------------------------
|
|
andrew@2
|
1275 void testApp::windowResized(int w, int h){
|
|
andrew@2
|
1276 screenWidth = ofGetWidth();
|
|
andrew@2
|
1277 screenHeight = ofGetHeight();
|
|
andrew@2
|
1278 stepSize = screenWidth / (float)(ARRAY_SIZE);
|
|
andrew@2
|
1279 }
|
|
andrew@2
|
1280
|
|
andrew@2
|
1281 double testApp::convertToBPM(double interval){
|
|
andrew@2
|
1282 //interval is in ms and is the tatum interval - eighth nbote - so 250ms for 120bpm
|
|
andrew@2
|
1283 return (30000/interval);
|
|
andrew@2
|
1284
|
|
andrew@2
|
1285 }
|
|
andrew@2
|
1286 /*
|
|
andrew@2
|
1287 noyt needed?
|
|
andrew@2
|
1288 float testApp::tempoIndexToMsec(int index){
|
|
andrew@2
|
1289 float msec;
|
|
andrew@2
|
1290 msec = index * (tempoMaximum - tempoMinimum) / ARRAY_SIZE;
|
|
andrew@2
|
1291 msec += tempoMinimum;
|
|
andrew@2
|
1292 return msec;
|
|
andrew@2
|
1293 }
|
|
andrew@2
|
1294
|
|
andrew@2
|
1295 float testApp::beatIndexToMsec(int index){
|
|
andrew@2
|
1296 float msec;
|
|
andrew@2
|
1297 msec = index * maxTempo / ARRAY_SIZE;
|
|
andrew@2
|
1298 msec += tempoMinimum;
|
|
andrew@2
|
1299 return msec;
|
|
andrew@2
|
1300 }
|
|
andrew@2
|
1301 */
|
|
andrew@2
|
1302 /*
|
|
andrew@2
|
1303
|
|
andrew@2
|
1304 bool testApp::filterBeatTime(double newBeatTime){
|
|
andrew@2
|
1305 bool newBeatFound = false;
|
|
andrew@2
|
1306 if ((newBeatTime - beatTimes.lastBeatTime) > 20 || beatTimes.lastBeatTime == 0){
|
|
andrew@2
|
1307
|
|
andrew@2
|
1308 crossUpdateArrays((float)(newBeatTime - beatTimes.lastBeatTime));
|
|
andrew@2
|
1309 beatTimes.lastBeatTime = newBeatTime;
|
|
andrew@2
|
1310 newBeatFound = true;
|
|
andrew@2
|
1311 }
|
|
andrew@2
|
1312 return newBeatFound;
|
|
andrew@2
|
1313 }
|
|
andrew@2
|
1314
|
|
andrew@2
|
1315 void testApp::crossUpdateArrays(float timeInterval){
|
|
andrew@2
|
1316
|
|
andrew@2
|
1317 int finalBeatIndex, tmpTempoIndex, startBeatIndex;
|
|
andrew@2
|
1318 //finalBeat has contribution from BEAT[finalBeat + INT.k] * TEMPO[Max_tempo + k] where INT = INTERVAL
|
|
andrew@2
|
1319 float interval;
|
|
andrew@2
|
1320 interval = timeInterval / maxTempo;//beatTimes.tatum;
|
|
andrew@2
|
1321 tempoDistribution.resetMaximumPosterior();
|
|
andrew@2
|
1322 beatDistribution.resetMaximumPosterior();
|
|
andrew@2
|
1323
|
|
andrew@2
|
1324
|
|
andrew@2
|
1325 int tmpBeatIndex;
|
|
andrew@2
|
1326 //&& interval > 0.8 idea?
|
|
andrew@2
|
1327 if (timeInterval > 0 && timeInterval < 12000 ){//need between 0 and 12 seconds only to update
|
|
andrew@2
|
1328
|
|
andrew@2
|
1329 for (tmpBeatIndex = 0;tmpBeatIndex < ARRAY_SIZE;tmpBeatIndex++){
|
|
andrew@2
|
1330
|
|
andrew@2
|
1331 tmpArray[tmpBeatIndex] = 0;
|
|
andrew@2
|
1332 float minusMsecToMakeUp = beatIndexToMsec(tmpBeatIndex) / interval;
|
|
andrew@2
|
1333 float plusMsecToMakeUp = beatIndexToMsec(ARRAY_SIZE - tmpBeatIndex) / interval;
|
|
andrew@2
|
1334 float convertMsecToTempoIndex = ARRAY_SIZE / (tempoMaximum - tempoMinimum) ;
|
|
andrew@2
|
1335
|
|
andrew@2
|
1336
|
|
andrew@2
|
1337 int minTempoIndex = -1 * (int)(minusMsecToMakeUp * convertMsecToTempoIndex);
|
|
andrew@2
|
1338 int maxTempoIndex = (int)(plusMsecToMakeUp * convertMsecToTempoIndex);
|
|
andrew@2
|
1339
|
|
andrew@2
|
1340
|
|
andrew@2
|
1341 if (tmpBeatIndex == beatDistribution.maximumIndex){
|
|
andrew@2
|
1342 minTmpDebug = tempoDistribution.maximumIndex + minTempoIndex;
|
|
andrew@2
|
1343 maxTmpDebug = tempoDistribution.maximumIndex + maxTempoIndex;
|
|
andrew@2
|
1344 debugArray[0] = beatDistribution.maximumIndex;//
|
|
andrew@2
|
1345 debugArray[1] = timeInterval;
|
|
andrew@2
|
1346 debugArray[2] = interval;//beatDistribution.maximumIndex;
|
|
andrew@2
|
1347 debugArray[3] = tempoDistribution.maximumIndex;
|
|
andrew@2
|
1348 }
|
|
andrew@2
|
1349
|
|
andrew@2
|
1350 for (tmpTempoIndex = minTempoIndex;tmpTempoIndex <= maxTempoIndex;tmpTempoIndex++){
|
|
andrew@2
|
1351
|
|
andrew@2
|
1352 if ((tempoDistribution.maximumIndex + tmpTempoIndex) >= 0
|
|
andrew@2
|
1353 && (tempoDistribution.maximumIndex + tmpTempoIndex) < ARRAY_SIZE
|
|
andrew@2
|
1354 && (tmpBeatIndex - (int)(interval*tmpTempoIndex)) >= 0
|
|
andrew@2
|
1355 && (tmpBeatIndex - (int)(interval*tmpTempoIndex))< ARRAY_SIZE){
|
|
andrew@2
|
1356 tmpArray[tmpBeatIndex] += beatDistribution.posterior[tmpBeatIndex - (int)(interval*tmpTempoIndex)] * tempoDistribution.posterior[(int)tempoDistribution.maximumIndex + tmpTempoIndex];
|
|
andrew@2
|
1357 }
|
|
andrew@2
|
1358 }//end for tmpTmepo
|
|
andrew@2
|
1359
|
|
andrew@2
|
1360
|
|
andrew@2
|
1361
|
|
andrew@2
|
1362 }
|
|
andrew@2
|
1363
|
|
andrew@2
|
1364 float tmpFloat;
|
|
andrew@2
|
1365 for (tmpBeatIndex = 0;tmpBeatIndex < ARRAY_SIZE;tmpBeatIndex++){
|
|
andrew@2
|
1366 //debug - dont actually update::
|
|
andrew@2
|
1367
|
|
andrew@2
|
1368 tmpFloat = beatDistribution.posterior[tmpBeatIndex];
|
|
andrew@2
|
1369 beatDistribution.posterior[tmpBeatIndex] = tmpArray[tmpBeatIndex];
|
|
andrew@2
|
1370 tmpArray[tmpBeatIndex] = tmpFloat;
|
|
andrew@2
|
1371 }
|
|
andrew@2
|
1372 beatDistribution.renormaliseArray(&beatDistribution.posterior[0], ARRAY_SIZE);
|
|
andrew@2
|
1373
|
|
andrew@2
|
1374 } //end if
|
|
andrew@2
|
1375
|
|
andrew@2
|
1376
|
|
andrew@2
|
1377 }
|
|
andrew@2
|
1378
|
|
andrew@2
|
1379
|
|
andrew@2
|
1380 void testApp::updateTempoProcess(double cpuTime, string onsetDescription){
|
|
andrew@2
|
1381
|
|
andrew@2
|
1382 if (filterBeatTime(cpuTime) == true){
|
|
andrew@2
|
1383 //checks for no repeat
|
|
andrew@2
|
1384
|
|
andrew@2
|
1385 if (onsetDescription == "kick")
|
|
andrew@2
|
1386 beatTimes.addBeatTime(cpuTime, 1);
|
|
andrew@2
|
1387 else
|
|
andrew@2
|
1388 beatTimes.addBeatTime(cpuTime, 2);
|
|
andrew@2
|
1389
|
|
andrew@2
|
1390
|
|
andrew@2
|
1391 //recalculate the distribution
|
|
andrew@2
|
1392 int altIndex = 0;
|
|
andrew@2
|
1393
|
|
andrew@2
|
1394 tempoDataString = "Tatum :";
|
|
andrew@2
|
1395 tempoDataString += ofToString(beatTimes.tatum, 2);
|
|
andrew@2
|
1396 tempoDataString += " BPM ";
|
|
andrew@2
|
1397 tempoDataString += ofToString((double)30000/beatTimes.tatum, 2);
|
|
andrew@2
|
1398
|
|
andrew@2
|
1399 timeString = "Last BEAT ";
|
|
andrew@2
|
1400 timeString += ofToString(beatTimes.lastBeatTime);
|
|
andrew@2
|
1401 timeString += " CLICK ";
|
|
andrew@2
|
1402 timeString += ofToString(beatTimes.lastClickTime);
|
|
andrew@2
|
1403 timeString += " DIFDF ";
|
|
andrew@2
|
1404 timeString += ofToString(beatTimes.timeDifference);
|
|
andrew@2
|
1405 timeString += " segment ";
|
|
andrew@2
|
1406 timeString += ofToString(beatTimes.beatSegment);
|
|
andrew@2
|
1407
|
|
andrew@2
|
1408
|
|
andrew@2
|
1409 for (altIndex = 0;altIndex< 16;altIndex++){
|
|
andrew@2
|
1410 tempoInterval = beatTimes.intervalDifferences[beatTimes.index][altIndex];
|
|
andrew@2
|
1411 integerMultipleOfTatum = beatTimes.relativeIntervals[altIndex][1];
|
|
andrew@2
|
1412
|
|
andrew@2
|
1413
|
|
andrew@2
|
1414 ///NEW VERSION
|
|
andrew@2
|
1415 tempoUpdateStrings[altIndex] = "";
|
|
andrew@2
|
1416 double timeInterval = beatTimes.beatTimes[beatTimes.index] - beatTimes.beatTimes[altIndex];
|
|
andrew@2
|
1417 //raw time difference
|
|
andrew@2
|
1418 beatTimes.intervalDifferences[beatTimes.index][altIndex] = 0;
|
|
andrew@2
|
1419 beatTimes.intervalUsed[beatTimes.index][altIndex] = false;
|
|
andrew@2
|
1420
|
|
andrew@2
|
1421 if (onsetType == "kick")
|
|
andrew@2
|
1422 beatTimes.OnsetIsKick[beatTimes.index] = true;
|
|
andrew@2
|
1423 else
|
|
andrew@2
|
1424 beatTimes.OnsetIsKick[beatTimes.index] = false;
|
|
andrew@2
|
1425
|
|
andrew@2
|
1426
|
|
andrew@2
|
1427
|
|
andrew@2
|
1428 if (!accompanimentStarted){
|
|
andrew@2
|
1429 //if we need to find tempo and start use this method
|
|
andrew@2
|
1430 //we have 'started' once std dev is sufficiently low
|
|
andrew@2
|
1431
|
|
andrew@2
|
1432 updateTempoIfWithinRange(timeInterval);//taken as being the tatum interval
|
|
andrew@2
|
1433
|
|
andrew@2
|
1434
|
|
andrew@2
|
1435
|
|
andrew@2
|
1436 for (int i = 1;i <= 4;i++){
|
|
andrew@2
|
1437 //we test the main beats and the two bar (16 tatum intervals)
|
|
andrew@2
|
1438
|
|
andrew@2
|
1439 double testInterval = timeInterval / 2*i;//pow(2, i);//pow(2.0, i);
|
|
andrew@2
|
1440
|
|
andrew@2
|
1441 if (updateTempoIfWithinRange(testInterval)){
|
|
andrew@2
|
1442 printf("test time %f, beats %i\n", testInterval, i);
|
|
andrew@2
|
1443
|
|
andrew@2
|
1444 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
|
|
andrew@2
|
1445 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
|
|
andrew@2
|
1446 //xx what if two within range here?
|
|
andrew@2
|
1447
|
|
andrew@2
|
1448 tempoUpdateStrings[altIndex] = "Tempo Updates (";
|
|
andrew@2
|
1449 tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0);
|
|
andrew@2
|
1450 tempoUpdateStrings[altIndex] += ") : [";
|
|
andrew@2
|
1451 tempoUpdateStrings[altIndex] += ofToString(altIndex);
|
|
andrew@2
|
1452 tempoUpdateStrings[altIndex] += "]] : ";
|
|
andrew@2
|
1453 tempoUpdateStrings[altIndex] += ofToString(timeInterval);
|
|
andrew@2
|
1454 tempoUpdateStrings[altIndex] += ", ioi:";
|
|
andrew@2
|
1455 tempoUpdateStrings[altIndex] += ofToString(i);
|
|
andrew@2
|
1456 //tempoUpdateStrings[altIndex] += "";
|
|
andrew@2
|
1457
|
|
andrew@2
|
1458 }
|
|
andrew@2
|
1459
|
|
andrew@2
|
1460 }
|
|
andrew@2
|
1461
|
|
andrew@2
|
1462 double testInterval = timeInterval / 16;//pow(2, i);//pow(2.0, i);
|
|
andrew@2
|
1463 if (updateTempoIfWithinRange(testInterval)){
|
|
andrew@2
|
1464 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
|
|
andrew@2
|
1465 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
|
|
andrew@2
|
1466 }
|
|
andrew@2
|
1467
|
|
andrew@2
|
1468 }else{
|
|
andrew@2
|
1469 //OLD VERSON
|
|
andrew@2
|
1470 //THIS USES THE CURRENT TEMPO ESTIMATE TO DECIDE WHAT THE BEST INTERVAL IS
|
|
andrew@2
|
1471 //&& integerMultipleOfTatum % 2 == 0 removed below XXX put back
|
|
andrew@2
|
1472 if (altIndex != beatTimes.index && integerMultipleOfTatum < 17
|
|
andrew@2
|
1473 && integerMultipleOfTatum > 0 && beatTimes.startIndex > 8//beattimes.index > 8 - the start
|
|
andrew@2
|
1474 && integerMultipleOfTatum%2 == 0){//mod 2 - i.e. proper beat intervals only
|
|
andrew@2
|
1475
|
|
andrew@2
|
1476 double testInterval = timeInterval / integerMultipleOfTatum;
|
|
andrew@2
|
1477
|
|
andrew@2
|
1478 if (updateTempoIfWithinRange(testInterval)){
|
|
andrew@2
|
1479
|
|
andrew@2
|
1480 beatTimes.intervalUsed[beatTimes.index][altIndex] = true;
|
|
andrew@2
|
1481 beatTimes.intervalDifferences[beatTimes.index][altIndex] = testInterval;
|
|
andrew@2
|
1482
|
|
andrew@2
|
1483 if (paused == false){
|
|
andrew@2
|
1484 tempoUpdateStrings[altIndex] = "Tempo Updates : (";
|
|
andrew@2
|
1485 tempoUpdateStrings[altIndex] += ofToString(beatTimes.index, 0);
|
|
andrew@2
|
1486 tempoUpdateStrings[altIndex] += ") : [";
|
|
andrew@2
|
1487 tempoUpdateStrings[altIndex] += ofToString(altIndex, 0);
|
|
andrew@2
|
1488 tempoUpdateStrings[altIndex] += "] :: ";
|
|
andrew@2
|
1489 tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum);
|
|
andrew@2
|
1490 tempoUpdateStrings[altIndex] += " intervals :: ";
|
|
andrew@2
|
1491 tempoUpdateStrings[altIndex] += ofToString(tempoInterval);
|
|
andrew@2
|
1492 tempoUpdateStrings[altIndex] += " ms.";
|
|
andrew@2
|
1493 // tempoUpdateStrings[altIndex] += ", ioi:";
|
|
andrew@2
|
1494
|
|
andrew@2
|
1495 // tempoUpdateStrings[altIndex] += ofToString(integerMultipleOfTatum);
|
|
andrew@2
|
1496
|
|
andrew@2
|
1497
|
|
andrew@2
|
1498
|
|
andrew@2
|
1499
|
|
andrew@2
|
1500 }//end if not paused
|
|
andrew@2
|
1501
|
|
andrew@2
|
1502
|
|
andrew@2
|
1503 }//end if good interval to update
|
|
andrew@2
|
1504
|
|
andrew@2
|
1505 }//end if not same index etc
|
|
andrew@2
|
1506
|
|
andrew@2
|
1507
|
|
andrew@2
|
1508 }
|
|
andrew@2
|
1509
|
|
andrew@2
|
1510
|
|
andrew@2
|
1511
|
|
andrew@2
|
1512 }//end for all intervals
|
|
andrew@2
|
1513
|
|
andrew@2
|
1514 sendMaxTempo();
|
|
andrew@2
|
1515 }//end if new beat time
|
|
andrew@2
|
1516 double tempoEstimate = tempoDistribution.getIntegratedEstimateIndex();
|
|
andrew@2
|
1517 tempoDistribution.calculateStandardDeviation();
|
|
andrew@2
|
1518 tempoStdDev = tempoDistribution.standardDeviation;
|
|
andrew@2
|
1519
|
|
andrew@2
|
1520 }
|
|
andrew@2
|
1521
|
|
andrew@2
|
1522
|
|
andrew@2
|
1523 bool testApp::updateTempoIfWithinRange(double timeInterval){
|
|
andrew@2
|
1524
|
|
andrew@2
|
1525 bool updated = false;
|
|
andrew@2
|
1526
|
|
andrew@2
|
1527 if (timeInterval > tempoMinimum && timeInterval < tempoMaximum ){
|
|
andrew@2
|
1528 calculateTempoUpdate(timeInterval);
|
|
andrew@2
|
1529 updated = true;
|
|
andrew@2
|
1530 }
|
|
andrew@2
|
1531
|
|
andrew@2
|
1532 return updated;
|
|
andrew@2
|
1533 }
|
|
andrew@2
|
1534
|
|
andrew@2
|
1535
|
|
andrew@2
|
1536 */
|
|
andrew@2
|
1537 //end
|
|
andrew@2
|
1538 /*
|
|
andrew@2
|
1539 void testApp::calculateTempoUpdate(double tempoInterval){
|
|
andrew@2
|
1540
|
|
andrew@2
|
1541
|
|
andrew@2
|
1542 tempoDistribution.resetPrior();
|
|
andrew@2
|
1543 //need to relook at likelihood for the tempo distribution - not the same as....
|
|
andrew@2
|
1544 tempoDistribution.setGaussianLikelihood(ARRAY_SIZE * (tempoInterval-tempoMinimum)/(tempoMaximum - tempoMinimum), tempoDistribution.likelihoodStdDev);
|
|
andrew@2
|
1545 tempoDistribution.calculatePosterior();
|
|
andrew@2
|
1546 tempoDistribution.renormalisePosterior();
|
|
andrew@2
|
1547
|
|
andrew@2
|
1548 //did take pic of screen here - see initialiser4
|
|
andrew@2
|
1549 }
|
|
andrew@2
|
1550 */
|
|
andrew@2
|
1551
|