comparison src/AudioEventMatcher.cpp @ 16:680ba08e9925

Auto synchroniser added using the elastique~ object in max
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 06 Feb 2012 12:18:40 +0000
parents 780def3a1f36
children c96b18dd0f48
comparison
equal deleted inserted replaced
15:780def3a1f36 16:680ba08e9925
13 const int matchWindowWidth = 6000; 13 const int matchWindowWidth = 6000;
14 14
15 AudioEventMatcher::AudioEventMatcher(){ 15 AudioEventMatcher::AudioEventMatcher(){
16 16
17 17
18 pitchLikelihoodToNoise = 0.4;//more noise 18 pitchLikelihoodToNoise = 0.9;//more noise
19 onsetLikelihoodToNoise = 0.3; 19
20 onsetLikelihoodToNoise = 0.4;
20 onsetLikelihoodWidth = 20;//in ms 21 onsetLikelihoodWidth = 20;//in ms
21 22
22 setArraySizes(); 23 setArraySizes();
23 24
24 usingRealTime = false; 25 usingRealTime = false;
52 bayesianStruct.relativeSpeedPrior.getMaximum(); 53 bayesianStruct.relativeSpeedPrior.getMaximum();
53 54
54 bayesianStruct.resetSize(matchWindowWidth); 55 bayesianStruct.resetSize(matchWindowWidth);
55 bayesianStruct.setPositionDistributionScalar(1); 56 bayesianStruct.setPositionDistributionScalar(1);
56 57
58 }
59
60 void AudioEventMatcher::loadAudioFiles(){
61 recordedTracks.loadTestAudio();
62 synchroniser.fileLengthSamples = recordedTracks.loadedAudioFiles[0].fileLoader.totalNumberOfSamples;
63 printf("synchroniser has %f samples\n", synchroniser.fileLengthSamples);
57 } 64 }
58 65
59 void AudioEventMatcher::startPlaying(){ 66 void AudioEventMatcher::startPlaying(){
60 bayesianStruct.setStartPlaying(); 67 bayesianStruct.setStartPlaying();
61 currentAlignmentPosition = 0; 68 currentAlignmentPosition = 0;
90 // double speedtmp = bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); 97 // double speedtmp = bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate);
91 // currentAlignmentTime = newTime; 98 // currentAlignmentTime = newTime;
92 currentAlignmentPosition = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate); 99 currentAlignmentPosition = bayesianStruct.posterior.getIndexInRealTerms(bayesianStruct.posterior.MAPestimate);
93 currentAlignmentPosition += (newTime - lastAlignmentTime) * bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate); 100 currentAlignmentPosition += (newTime - lastAlignmentTime) * bayesianStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesianStruct.relativeSpeedPosterior.MAPestimate);
94 101
102
103 synchroniser.updateRecordedPosition(currentAlignmentPosition);
104
105 synchroniser.updateOutputSpeed();
106
95 bayesianStruct.projectDistribution(newTime, currentAlignmentPosition, projectedPrior);//prior gets updated to where we are now 107 bayesianStruct.projectDistribution(newTime, currentAlignmentPosition, projectedPrior);//prior gets updated to where we are now
96 108
97 // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition); 109 // printf("ALIGN pos %f time diff %f (now %f , last %f)speed %f :: ALIGN BEST %f\n", tmp, timetmp, (double)ofGetElapsedTimeMillis(), lastAlignmentTime, speedtmp, currentAlignmentPosition);
98 } 110 }
99 111
115 //bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); 127 //bayesianStruct.posterior.drawVector(0, bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow);
116 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); 128 //bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow);
117 //bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); 129 //bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow);
118 130
119 ofDrawBitmapString("pitch "+ofToString(recentPitch, 2)+", Time "+ofToString(recentTime, 0), 20, 20); 131 ofDrawBitmapString("pitch "+ofToString(recentPitch, 2)+", Time "+ofToString(recentTime, 0), 20, 20);
132
133 string alignString = " align "+ofToString(currentAlignmentPosition, 2);
134 alignString += " playing "+ofToString(synchroniser.playingPositionRatio, 5);
135 alignString += " "+ofToString(synchroniser.playingPositionMillis)+" ms";
136 ofDrawBitmapString(alignString, 20, 50);
120 137
121 ofDrawBitmapString("pos "+ofToString(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.playPosition), 200,600); 138 ofDrawBitmapString("pos "+ofToString(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.playPosition), 200,600);
122 } 139 }
123 140
124 void AudioEventMatcher::setScreenDisplayTimes(){ 141 void AudioEventMatcher::setScreenDisplayTimes(){
164 181
165 //green line at current best estimate 182 //green line at current best estimate
166 ofSetColor(0,255,0);//green scrolling line best position 183 ofSetColor(0,255,0);//green scrolling line best position
167 double currentEstimateIndex = (currentAlignmentPosition - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis; 184 double currentEstimateIndex = (currentAlignmentPosition - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis;
168 ofLine(currentEstimateIndex, bayesPositionWindow.y, currentEstimateIndex, bayesPositionWindow.y + bayesPositionWindow.height); 185 ofLine(currentEstimateIndex, bayesPositionWindow.y, currentEstimateIndex, bayesPositionWindow.y + bayesPositionWindow.height);
186
187
188 ofSetColor(0,255,255);//synchroniser position
189 currentEstimateIndex = (synchroniser.playingPositionMillis - screenStartTimeMillis)*ofGetWidth()/screenWidthMillis;
190 ofLine(currentEstimateIndex, bayesLikelihoodWindow.y, currentEstimateIndex, bayesLikelihoodWindow.y + bayesPositionWindow.height);
191
192
169 193
170 //draw track by track likelihoods 194 //draw track by track likelihoods
171 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){ 195 for (int i = 0; i <recordedTracks.numberOfAudioTracks;i++){
172 ofSetColor(200,255,50);//channel likelihoods in yellow 196 ofSetColor(200,255,50);//channel likelihoods in yellow
173 likelihoodVisualisation[i].drawConstrainedVector(likelihoodVisualisation[i].getRealTermsAsIndex(screenStartTimeMillis), likelihoodVisualisation[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window); 197 likelihoodVisualisation[i].drawConstrainedVector(likelihoodVisualisation[i].getRealTermsAsIndex(screenStartTimeMillis), likelihoodVisualisation[i].getRealTermsAsIndex(screenEndTimeMillis), 0, ofGetWidth(), recordedTracks.loadedAudioFiles[i].fileLoader.onsetDetect.window);
300 double quantity = 0; 324 double quantity = 0;
301 if (channel <= recordedTracks.numberOfAudioTracks){ 325 if (channel <= recordedTracks.numberOfAudioTracks){
302 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ 326 for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){
303 327
304 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) { 328 if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) {
305 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 10); 329 quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 16);
306 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity); 330 bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity);
307 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true; 331 recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true;
308 numberOfMatches++; 332 numberOfMatches++;
309 } 333 }
310 else{ 334 else{
335 359
336 } 360 }
337 361
338 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ 362 double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){
339 363
364 double scaleFactor = scale ;//* pitchOne / 110.0;
365
366
340 double distance = abs(pitchOne - pitchTwo); 367 double distance = abs(pitchOne - pitchTwo);
341 if (distance < scale) 368 if (distance < scaleFactor)
342 distance = 1 - (distance/scale); 369 distance = 1 - (distance/scaleFactor);
343 else 370 else
344 distance = 0; 371 distance = 0;
345 372
346 // printf("[pitch distance %f vs %f = %f\n", pitchOne, pitchTwo, distance); 373 // printf("[pitch distance %f vs %f = %f\n", pitchOne, pitchTwo, distance);
347 return distance; 374 return distance;
348 375
349 } 376 }
350 377
351 378
352 bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){ 379 bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){
353 if (abs(recordedPitch - livePitch) < 40) 380 if (abs(recordedPitch - livePitch) < 16)
354 return true; 381 return true;
355 else 382 else
356 return false; 383 return false;
357 } 384 }
358 385