comparison src/AudioEventMatcher.cpp @ 32:4be22a1a0e24

added in chroma comparison for fourth channel (guitar)
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 02 Apr 2012 17:19:22 +0100
parents c47ea39b830d
children 0d52ba6844b9
comparison
equal deleted inserted replaced
31:02f659277346 32:4be22a1a0e24
9 9
10 #include "AudioEventMatcher.h" 10 #include "AudioEventMatcher.h"
11 11
12 12
13 const int matchWindowWidth = 6000; 13 const int matchWindowWidth = 6000;
14 const float pitchCutOff = 16;//within which pitches are even considered
14 15
15 AudioEventMatcher::AudioEventMatcher(){ 16 AudioEventMatcher::AudioEventMatcher(){
16 17
17 18
18 pitchLikelihoodToNoise = 0.6;//more noise 19 pitchLikelihoodToNoise = 0.6;//more noise
20 chromaLikelihoodToNoise = 0.5;//lower => more noise, higher more weight for events
21 chromaLikelihoodWidth = 50;//ms round onset event
19 22
20 onsetLikelihoodToNoise = 0.4; 23 onsetLikelihoodToNoise = 0.4;
21 onsetLikelihoodWidth = 10;//in ms 24 onsetLikelihoodWidth = 10;//in ms
22 25
23 setArraySizes(); 26 setArraySizes();
40 43
41 44
42 void AudioEventMatcher::setWindowDimensions(){ 45 void AudioEventMatcher::setWindowDimensions(){
43 double startHeight = recordedTracks.numberOfAudioTracks * recordedTracks.trackScreenHeight; 46 double startHeight = recordedTracks.numberOfAudioTracks * recordedTracks.trackScreenHeight;
44 double heightAvailable = 1 - startHeight; 47 double heightAvailable = 1 - startHeight;
45 heightAvailable /= NUMBER_OF_CHANNELS; 48 heightAvailable /= numberOfChannels;
46 49
47 bayesPositionWindow.setToRelativeSize(0, startHeight, 1, heightAvailable); 50 bayesPositionWindow.setToRelativeSize(0, startHeight, 1, heightAvailable);
48 bayesLikelihoodWindow.setToRelativeSize(0, startHeight + 1*heightAvailable, 1, heightAvailable); 51 bayesLikelihoodWindow.setToRelativeSize(0, startHeight + 1*heightAvailable, 1, heightAvailable);
49 bayesTempoWindow.setToRelativeSize(0, startHeight + 2*heightAvailable, 1, heightAvailable); 52 bayesTempoWindow.setToRelativeSize(0, startHeight + 2*heightAvailable, 1, heightAvailable);
50 53
208 synchroniser.updateRecordedPosition(currentAlignmentPosition, newTime); 211 synchroniser.updateRecordedPosition(currentAlignmentPosition, newTime);
209 212
210 synchroniser.updateOutputSpeed(); 213 synchroniser.updateOutputSpeed();
211 214
212 bayesianStruct.projectDistribution(newTime, currentAlignmentPosition, projectedPrior);//prior gets updated to where we are now 215 bayesianStruct.projectDistribution(newTime, currentAlignmentPosition, projectedPrior);//prior gets updated to where we are now
213 printf("alignment %i:: %i\n", newTime, (int) currentAlignmentPosition); 216
217 // printf("updateBestAlignment:: alignment %i:: %i\n", newTime, (int) currentAlignmentPosition);
214 218
215 // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition); 219 // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition);
216 } 220 }
217 221
218 void AudioEventMatcher::draw(){ 222 void AudioEventMatcher::draw(){
223
224 //MAIN DRAW FUNCTION FOR ALL
225
219 //draw some outlines in blue 226 //draw some outlines in blue
220 ofSetColor(20,200,200); 227 ofSetColor(20,200,200);
221 bayesPositionWindow.drawOutline(); 228 bayesPositionWindow.drawOutline();
222 bayesTempoWindow.drawOutline(); 229 bayesTempoWindow.drawOutline();
223 230
231 drawBayesianDistributions(); 238 drawBayesianDistributions();
232 239
233 //bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); 240 //bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow);
234 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); 241 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow);
235 //bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); 242 //bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow);
236 string tmpStr = "pitch "+ofToString(recentPitch, 2); 243
237 tmpStr += " Nearest "+ofToString(pitchOfNearestMatch,2);
238 tmpStr += " dist "+ofToString(distanceOfNearestMatch, 2);
239 tmpStr += ", Time "+ofToString(recentTime, 0);
240 ofDrawBitmapString(tmpStr, 20, 20);
241
242
243
244 string alignString = " align "+ofToString(currentAlignmentPosition, 2);
245 alignString += " playing "+ofToString(synchroniser.playingPositionRatio, 5);
246 alignString += " pos "+ofToString(synchroniser.playingPositionMillis,0)+" ms";
247 alignString += " rec pos "+ofToString(synchroniser.recordedPositionMillis,0)+" ms";
248 ofDrawBitmapString(alignString, 20, 50);
249
250 ofDrawBitmapString("pos "+ofToString(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.playPosition), 200,600);
251
252 temporal.drawTempoArray(bayesLikelihoodWindow); 244 temporal.drawTempoArray(bayesLikelihoodWindow);
253 245
254 drawRecordedTempo(); 246 drawRecordedTempo();
255 drawPlayingTempo(); 247 drawPlayingTempo();
256 248
302 }*/ 294 }*/
303 } 295 }
304 296
305 void AudioEventMatcher::drawBayesianDistributions(){ 297 void AudioEventMatcher::drawBayesianDistributions(){
306 298
307 299
300 drawPositionWindow();
301
302 // bayesianStruct.likelihood.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesLikelihoodWindow);
303
304 bayesianStruct.relativeSpeedPosterior.drawConstrainedVector(0, bayesianStruct.relativeSpeedPosterior.arraySize, 0, ofGetWidth(), bayesTempoWindow);
305
306
307 drawTrackLikelihoods();
308
309 // int priorStartIndex = bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis);
310 // int priorEndIndex = bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis);
311 // ofSetColor(0,200,200);//recent prior
312 // recentPrior.drawConstrainedVector(priorStartIndex, priorEndIndex, 0, ofGetWidth(), bayesPositionWindow);
313
314 drawInfo();
315
316
317 }
318
319 void AudioEventMatcher::drawPositionWindow(){
308 int startIndex = bayesianStruct.posterior.getRealTermsAsIndex(screenStartTimeMillis); 320 int startIndex = bayesianStruct.posterior.getRealTermsAsIndex(screenStartTimeMillis);
309 int endIndex = bayesianStruct.posterior.getRealTermsAsIndex(screenEndTimeMillis); 321 int endIndex = bayesianStruct.posterior.getRealTermsAsIndex(screenEndTimeMillis);
310
311 bayesianStruct.posterior.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesPositionWindow);
312
313 string tmpString = "start "+ofToString(screenStartTimeMillis)+" (index "+ofToString(startIndex)+"), end "+ofToString(screenEndTimeMillis); 322 string tmpString = "start "+ofToString(screenStartTimeMillis)+" (index "+ofToString(startIndex)+"), end "+ofToString(screenEndTimeMillis);
314 ofDrawBitmapString(tmpString, bayesPositionWindow.x+20, bayesPositionWindow.y+20); 323 ofDrawBitmapString(tmpString, bayesPositionWindow.x+20, bayesPositionWindow.y+20);
315 324
316 // bayesianStruct.likelihood.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesLikelihoodWindow); 325 //draw posterior in the bayes position window
317 326 ofSetColor(255,0,255);
318 bayesianStruct.relativeSpeedPosterior.drawConstrainedVector(0, bayesianStruct.relativeSpeedPosterior.arraySize, 0, ofGetWidth(), bayesTempoWindow); 327 bayesianStruct.posterior.drawConstrainedVector(startIndex, endIndex, 0, ofGetWidth(), bayesPositionWindow);
319 328
329 //green line at current best estimate
330 ofSetColor(0,255,0);//green scrolling line best position
331 double currentEstimateIndex = (currentAlignmentPosition - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis;
332 ofLine(currentEstimateIndex, bayesPositionWindow.y, currentEstimateIndex, bayesPositionWindow.y + bayesPositionWindow.height);
333
334
335 ofSetColor(0,255,255);//synchroniser position
336 currentEstimateIndex = (synchroniser.playingPositionMillis - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis;
337 ofLine(currentEstimateIndex, bayesLikelihoodWindow.y, currentEstimateIndex, bayesLikelihoodWindow.y + bayesPositionWindow.height);
338
339 ofSetColor(255,0,100);//purple prior
340 bayesianStruct.prior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesPositionWindow);
341
342 ofSetColor(255,0,0);//projected prior in red
343 projectedPrior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesPositionWindow);
344
345
346
347 }
348
349 void AudioEventMatcher::drawTrackLikelihoods(){
350 //draw track by track likelihoods
351 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){
352 ofSetColor(200,255,50);//channel likelihoods in yellow
353 likelihoodVisualisation[i].drawConstrainedVector(likelihoodVisualisation[i].getRealTermsAsIndex(screenStartTimeMillis), likelihoodVisualisation[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window);
354
355 ofSetColor(0,255,150);//channel priors
356 recentPriors[i].drawConstrainedVector(recentPriors[i].getRealTermsAsIndex(screenStartTimeMillis), recentPriors[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window);
357
358
359 ofSetColor(255);
360 ofDrawBitmapString("recent event "+ofToString(recentEventTime[i]), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.x + 20, recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.y + recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.height - 10);
361 }
362 }
363
364
365 void AudioEventMatcher::drawInfo(){
320 string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0)); 366 string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0));
321 tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset); 367 tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset);
322 tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis)); 368 tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis));
323 ofDrawBitmapString(tmpStr, 20,140); 369 ofDrawBitmapString(tmpStr, 20,140);
324 tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate); 370 tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate);
325 ofDrawBitmapString(tmpStr, 20, 180); 371 ofDrawBitmapString(tmpStr, 20, 180);
326
327 ofDrawBitmapString("screenwidth "+ofToString(screenWidthMillis), 20, 800); 372 ofDrawBitmapString("screenwidth "+ofToString(screenWidthMillis), 20, 800);
328 373
329 //green line at current best estimate 374 ofSetColor(255);
330 ofSetColor(0,255,0);//green scrolling line best position 375 tmpStr = "pitch "+ofToString(recentPitch, 2);
331 double currentEstimateIndex = (currentAlignmentPosition - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis; 376 tmpStr += " Nearest "+ofToString(pitchOfNearestMatch,2);
332 ofLine(currentEstimateIndex, bayesPositionWindow.y, currentEstimateIndex, bayesPositionWindow.y + bayesPositionWindow.height); 377 tmpStr += " dist "+ofToString(distanceOfNearestMatch, 2);
333 378 tmpStr += ", Time "+ofToString(recentTime, 0);
334 379 ofDrawBitmapString(tmpStr, 20, 20);
335 ofSetColor(0,255,255);//synchroniser position 380
336 currentEstimateIndex = (synchroniser.playingPositionMillis - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis; 381 string alignString = " align "+ofToString(currentAlignmentPosition, 2);
337 ofLine(currentEstimateIndex, bayesLikelihoodWindow.y, currentEstimateIndex, bayesLikelihoodWindow.y + bayesPositionWindow.height); 382 alignString += " playing "+ofToString(synchroniser.playingPositionRatio, 5);
338 383 alignString += " pos "+ofToString(synchroniser.playingPositionMillis,0)+" ms";
339 384 alignString += " rec pos "+ofToString(synchroniser.recordedPositionMillis,0)+" ms";
340 385 ofDrawBitmapString(alignString, 20, 50);
341 //draw track by track likelihoods 386
342 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){ 387 ofDrawBitmapString("pos "+ofToString(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.playPosition), 200,600);
343 ofSetColor(200,255,50);//channel likelihoods in yellow
344 likelihoodVisualisation[i].drawConstrainedVector(likelihoodVisualisation[i].getRealTermsAsIndex(screenStartTimeMillis), likelihoodVisualisation[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window);
345
346 ofSetColor(0,255,150);//channel priors
347 recentPriors[i].drawConstrainedVector(recentPriors[i].getRealTermsAsIndex(screenStartTimeMillis), recentPriors[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window);
348
349
350 ofSetColor(255);
351 ofDrawBitmapString("recent event "+ofToString(recentEventTime[i]), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.x + 20, recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.y + recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window.height - 10);
352 }
353
354 int priorStartIndex = bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis);
355 int priorEndIndex = bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis);
356 // ofSetColor(0,200,200);//recent prior
357 // recentPrior.drawConstrainedVector(priorStartIndex, priorEndIndex, 0, ofGetWidth(), bayesPositionWindow);
358
359 ofSetColor(255,0,100);//purple prior
360 bayesianStruct.prior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesPositionWindow);
361
362 ofSetColor(255,0,0);
363 projectedPrior.drawConstrainedVector(bayesianStruct.prior.getRealTermsAsIndex(screenStartTimeMillis), bayesianStruct.prior.getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), bayesPositionWindow);
364
365
366 388
367 } 389 }
368 390
369 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ 391 void AudioEventMatcher::newPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){
370 if (pitchIn > 0){ 392 if (pitchIn > 0){
377 likelihoodVisualisation[1] = bayesianStruct.likelihood; 399 likelihoodVisualisation[1] = bayesianStruct.likelihood;
378 400
379 recentPitch = pitchIn;//for drawing 401 recentPitch = pitchIn;//for drawing
380 recentTime = timeIn; 402 recentTime = timeIn;
381 } 403 }
382 404 }
383 } 405
406
407 void AudioEventMatcher::newChromaEvent(const int& channel, float* chromaIn, const double& timeIn){
408
409 // could add event to the liveInput list? as in pitch event
410 // printf("match chroma channel %i\n", channel);
411
412 matchNewChromaEvent(channel, chromaIn, timeIn);//main pitch matching fn
413
414 likelihoodVisualisation[channel] = bayesianStruct.likelihood;
415
416
417 }
418
384 419
385 void AudioEventMatcher::newKickEvent(const double& timeIn){ 420 void AudioEventMatcher::newKickEvent(const double& timeIn){
386 // liveInput.addKickEvent(timeIn); 421 // liveInput.addKickEvent(timeIn);
387 matchNewOnsetEvent(0, timeIn); 422 matchNewOnsetEvent(0, timeIn);
388 likelihoodVisualisation[0] = bayesianStruct.likelihood; 423 likelihoodVisualisation[0] = bayesianStruct.likelihood;
410 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ 445 void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){
411 446
412 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets 447 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets
413 448
414 //start at beginning but OPTIMISE later 449 //start at beginning but OPTIMISE later
415
416
417 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; 450 bayesianStruct.likelihood.offset = bayesianStruct.prior.offset;
418 bayesianStruct.likelihood.zero();//set to zero 451 bayesianStruct.likelihood.zero();//set to zero
419 452
420 double quantity = 1;//likelihoodToNoiseRatio / numberOfMatches; 453 double quantity = 1;//likelihoodToNoiseRatio / numberOfMatches;
421 int numberOfMatchesFound = 0; 454 int numberOfMatchesFound = 0;
422 455
423
424 double startMatchingTime = bayesianStruct.likelihood.offset; 456 double startMatchingTime = bayesianStruct.likelihood.offset;
425 double endMatchingTime = bayesianStruct.likelihood.offset + matchWindowWidth; 457 double endMatchingTime = bayesianStruct.likelihood.offset + matchWindowWidth;
426 458 double millisTime = -1*INFINITY;//or 0 is fine
459 int checkIndex = 0;
427 if (channel <= recordedTracks.numberOfAudioTracks){ 460 if (channel <= recordedTracks.numberOfAudioTracks){
428 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ 461 while (millisTime < startMatchingTime) {
429 double millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime; 462 millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[checkIndex].millisTime;
463 checkIndex++;
464 }
465 for (int i = checkIndex;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size() && millisTime <= endMatchingTime;i++){
466 millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime;
430 if (millisTime >= startMatchingTime && millisTime <= endMatchingTime){ 467 if (millisTime >= startMatchingTime && millisTime <= endMatchingTime){
431 bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, onsetLikelihoodWidth, quantity); 468 bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, onsetLikelihoodWidth, quantity);
432 numberOfMatchesFound++; 469 numberOfMatchesFound++;
433 // printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset); 470 // printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset);
434 471
435 } 472 }//end if within limits (changed so it now is 4 sure)
436 } 473 }
437 } 474 }
438 475
439 if (numberOfMatchesFound > 0){ 476 if (numberOfMatchesFound > 0){
440 // bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length); 477 // bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length);
449 projectedPrior = bayesianStruct.prior; 486 projectedPrior = bayesianStruct.prior;
450 487
451 488
452 temporal.updateTempo(channel, timeIn); 489 temporal.updateTempo(channel, timeIn);
453 } 490 }
454
455
456 491
457 } 492 }
458 493
459 494
460 495
474 bayesianStruct.likelihood.zero();//set to zero 509 bayesianStruct.likelihood.zero();//set to zero
475 double newOnsetTime; 510 double newOnsetTime;
476 double closestDistance = INFINITY; 511 double closestDistance = INFINITY;
477 512
478 double quantity = 0; 513 double quantity = 0;
514 double totalLikelihoodAdded = 0;
479 if (channel <= recordedTracks.numberOfAudioTracks){ 515 if (channel <= recordedTracks.numberOfAudioTracks){
480 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ 516 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){
481 517
482 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) { 518 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) {
483 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 8); 519 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 12);
484 520
485 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity); 521 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity);
486 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true; 522 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true;
487 numberOfMatches++; 523 numberOfMatches++;
524 totalLikelihoodAdded += quantity;
488 } 525 }
489 else{ 526 else{
490 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = false; 527 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = false;
491 } 528 }
492 //checking nearest pitch 529 //checking nearest pitch
501 } 538 }
502 539
503 540
504 541
505 if (numberOfMatches > 0){//no point updating unless there is a match 542 if (numberOfMatches > 0){//no point updating unless there is a match
506 543 //replacing numberOfMatches with totalLike below...
507 bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); 544 bayesianStruct.likelihood.addConstant(totalLikelihoodAdded*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length));
508 545
509 //tmp set likelihood constant and calculate using that 546 //tmp set likelihood constant and calculate using that
510 //bayesianStruct.likelihood.zero(); 547 //bayesianStruct.likelihood.zero();
511 //bayesianStruct.likelihood.addConstant(1); 548 //bayesianStruct.likelihood.addConstant(1);
512 549
527 564
528 double scaleFactor = scale * pitchOne / 110.0; 565 double scaleFactor = scale * pitchOne / 110.0;
529 566
530 int multiplicationFactor = 1; 567 int multiplicationFactor = 1;
531 if (pitchTwo > 0){ 568 if (pitchTwo > 0){
532 int multiplicationFactor = round(pitchOne/pitchTwo); 569 multiplicationFactor = round(pitchOne/pitchTwo);
533 } 570 }
534 571
535 double distance = abs(pitchOne - pitchTwo*multiplicationFactor); 572 double distance = abs(pitchOne - pitchTwo*multiplicationFactor);
536 if (distance < scaleFactor) 573 if (distance < scaleFactor)
537 distance = 1 - (distance/scaleFactor); 574 distance = 1 - (distance/scaleFactor);
538 else 575 else
539 distance = 0; 576 distance = 0;
540 577
541 // printf("[pitch distance %f vs %f = %f\n", pitchOne, pitchTwo, distance); 578 //printf("[pitch distance %f vs %f, factor %i = %f\n", pitchOne, pitchTwo, multiplicationFactor, distance);
542 return distance; 579 return distance;
543 580
544 } 581 }
545 582
546 583
547 bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){ 584 bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){
548 585
549 if (livePitch > 0){ 586 if (livePitch > 0){
550 int multiplicationFactor = (int)(round(recordedPitch/livePitch)); 587 int multiplicationFactor = (int)(round(recordedPitch/livePitch));
551 588
552 if (abs(recordedPitch - livePitch * multiplicationFactor) < 16) 589 if (abs(recordedPitch - livePitch * multiplicationFactor) < pitchCutOff)
553 return true; 590 return true;
554 else 591 else
555 return false; 592 return false;
556 }else { 593 }else {
557 return false; 594 return false;
558 } 595 }
559 596
560 } 597 }
561 598
562 599
600 void AudioEventMatcher::matchNewChromaEvent(const int& channel, float* chromaIn, const double& timeIn){
601 //start at beginning but OPTIMISE later
602
603 bayesianStruct.updateBayesianDistributions(timeIn);//moves the posterior up into prior given the time interval and calculates new offsets
604
605 //set the likelihoods by matching the pitched note
606
607 int numberOfMatches = 0;
608 bayesianStruct.likelihood.zero();//set to zero
609 double newOnsetTime;
610 double closestDistance = INFINITY;
611
612 double quantity = 1;
613 double totalLikelihoodAdded = 0;
614
615 double startMatchingTime = bayesianStruct.likelihood.offset;
616 double endMatchingTime = bayesianStruct.likelihood.offset + matchWindowWidth;
617 double millisTime = -1*INFINITY;//or 0 is fine
618
619 int checkIndex = 0;
620 if (channel <= recordedTracks.numberOfAudioTracks){
621 while (millisTime < startMatchingTime) {
622 millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[checkIndex].millisTime;
623 checkIndex++;
624 }//go up to where we need to check from fast
625
626 for (int i = checkIndex;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size() && millisTime <= endMatchingTime;i++){
627 millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime;
628
629 if (millisTime >= startMatchingTime && millisTime <= endMatchingTime){
630 quantity = getChromaDistance(chromaIn, &recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].chromaValues[0]);
631 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, chromaLikelihoodWidth, quantity);
632
633 // bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, onsetLikelihoodWidth, quantity);
634 numberOfMatches++;
635 totalLikelihoodAdded += quantity;
636 printf("Adding CHROMA Gaussian for onset at time %.1f dist %.3f\n", millisTime, quantity);
637
638 }//end if within limits (changed so it now is 4 sure)
639 }
640 }
641
642
643 if (numberOfMatches > 0){//no point updating unless there is a match
644 //replacing numberOfMatches with totalLike below...
645
646 printf("CHROMA HAS %i MATCHES\n", numberOfMatches);
647
648 bayesianStruct.likelihood.addConstant(totalLikelihoodAdded*(1-chromaLikelihoodToNoise)/(chromaLikelihoodToNoise*bayesianStruct.likelihood.length));
649
650 bayesianStruct.calculatePosterior();
651 lastAlignmentTime = timeIn;//has to use the STAMPED time
652 recentEventTime[channel] = timeIn;
653
654 recentPriors[channel] = bayesianStruct.prior;
655 projectedPrior = bayesianStruct.prior;
656
657 temporal.eventTimes[channel].push_back(timeIn);
658 }
659
660 }
661
662
663 double AudioEventMatcher::getChromaDistance(float* chromaOne, float* chromaTwo){
664 double distance = 0;
665 double total = 0;
666 for (int i = 0;i < 12;i++){
667 distance += chromaOne[i]*chromaTwo[i];
668 total += chromaOne[i]*chromaOne[i] + (chromaTwo[i]*chromaTwo[i]);
669 }
670
671 distance /= sqrt(total);
672 return distance;
673 }
563 674
564 void AudioEventMatcher::windowResized(const int& w, const int& h){ 675 void AudioEventMatcher::windowResized(const int& w, const int& h){
565 recordedTracks.windowResized(w,h); 676 recordedTracks.windowResized(w,h);
566 bayesTempoWindow.resized(w,h); 677 bayesTempoWindow.resized(w,h);
567 bayesPositionWindow.resized(w,h); 678 bayesPositionWindow.resized(w,h);