Mercurial > hg > multitrack-audio-matcher
diff src/AudioEventMatcher.cpp @ 3:5e188c0035b6
checking the offsets of the arrays
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Wed, 01 Feb 2012 16:05:26 +0000 |
parents | 179c09199b3c |
children | 45b5cf9be377 |
line wrap: on
line diff
--- a/src/AudioEventMatcher.cpp Tue Jan 31 21:34:19 2012 +0000 +++ b/src/AudioEventMatcher.cpp Wed Feb 01 16:05:26 2012 +0000 @@ -13,11 +13,14 @@ const int matchWindowWidth = 6000; AudioEventMatcher::AudioEventMatcher(){ - - bayesTempoWindow.setToRelativeSize(0, 0.6, 1, 0.2); - bayesPositionWindow.setToRelativeSize(0, 0.8, 1, 0.2); - + bayesPositionWindow.setToRelativeSize(0, 0.4, 1, 0.2); + bayesTempoWindow.setToRelativeSize(0, 0.8, 1, 0.2); + bayesLikelihoodWindow.setToRelativeSize(0, 0.6, 1, 0.2); + setArraySizes(); + + usingRealTime = false; + bayesianStruct.realTimeMode = &usingRealTime; } @@ -32,8 +35,15 @@ } +void AudioEventMatcher::startPlaying(){ + bayesianStruct.setStartPlaying(); + //bayesianStruct.posterior.printArray(); +} + void AudioEventMatcher::draw(){ - //ofRect(20, 20, 300, 200); + ofSetColor(20,200,200); + bayesPositionWindow.drawOutline(); + bayesTempoWindow.drawOutline(); recordedTracks.drawTracks(); @@ -42,18 +52,32 @@ double screenWidthMillis = recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.framesToMillis(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.amplitudeNumber); + bayesianStruct.likelihood.drawVector(bayesianStruct.likelihood.getRealTermsAsIndex(0), bayesianStruct.likelihood.getRealTermsAsIndex(screenWidthMillis), bayesLikelihoodWindow); - bayesianStruct.likelihood.drawVector(0, screenWidthMillis, bayesTempoWindow); + bayesianStruct.relativeSpeedPosterior.drawVector(0, bayesianStruct.relativeSpeedPosterior.getRealTermsAsIndex(2), bayesTempoWindow); + + bayesianStruct.posterior.drawVector(bayesianStruct.posterior.getRealTermsAsIndex(0), bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis), bayesPositionWindow); + + string tmpStr = "zero is "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(0)); + tmpStr += " offsetis "+ofToString(bayesianStruct.posterior.offset); + tmpStr += " screenWidth = "+ofToString(bayesianStruct.posterior.getRealTermsAsIndex(screenWidthMillis)); + ofDrawBitmapString(tmpStr, 20,140); + tmpStr = "best est "+ofToString(bayesianStruct.bestEstimate); + ofDrawBitmapString(tmpStr, 20, 180); + + ofDrawBitmapString("screenamp "+ofToString(screenWidthMillis), 20, 100); + } void AudioEventMatcher::newPitchEvent(const double& pitchIn, const double& timeIn){ liveInput.addPitchEvent(pitchIn, timeIn); - recordedTracks.matchNewPitchEvent(0, pitchIn, timeIn); + matchNewPitchEvent(0, pitchIn, timeIn); } void AudioEventMatcher::newKickEvent(const double& timeIn){ +// liveInput.addKickEvent(time); matchNewOnsetEvent(0, timeIn); } @@ -64,8 +88,10 @@ //Needs just to set bounds for the matching process, not have TimeIn void AudioEventMatcher::matchNewOnsetEvent(const int& channel, const double& timeIn){ + + //start at beginning but OPTIMISE later - double likelihoodToNoise = 0.5; + double onsetLikelihoodToNoise = 0.5; double likelihoodWidth = 40; @@ -91,14 +117,112 @@ } } +// bayesianStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesianStruct.likelihood.length); + bayesianStruct.likelihood.addConstant(numberOfMatchesFound*(1-onsetLikelihoodToNoise)/(onsetLikelihoodToNoise*bayesianStruct.likelihood.length)); + bayesianStruct.likelihood.renormalise(); - //bayesStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesStruct.likelihood.length); + +} + + + +void AudioEventMatcher::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){ + //start at beginning but OPTIMISE later + updateBayesianDistributions(timeIn); + + ///set offsets +// bayesianStruct.likelihood.offset = bayesianStruct.prior.offset; + double pitchLikelihoodToNoise = 0.5; + int numberOfMatches = 0; + bayesianStruct.likelihood.zero();//set to zero + + double quantity = 0; + if (channel <= recordedTracks.numberOfAudioTracks){ + for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){ + + if (checkMatch(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) { + quantity = getPitchDistance(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn, 40); + bayesianStruct.likelihood.addGaussianShapeFromRealTime(recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime, 30, quantity); + recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true; + numberOfMatches++; + } + else{ + recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = false; + } + + } + } + + bayesianStruct.likelihood.addConstant(numberOfMatches*(1-pitchLikelihoodToNoise)/(pitchLikelihoodToNoise*bayesianStruct.likelihood.length)); + + recordedTracks.recentPitch = pitchIn; } +double AudioEventMatcher::getPitchDistance(const double& pitchOne, const double& pitchTwo, const double& scale){ + + double distance = abs(pitchOne - pitchTwo); + if (distance < scale) + distance = 1 - (distance/scale); + else + distance = 0; + +// printf("[pitch distance %f vs %f = %f\n", pitchOne, pitchTwo, distance); + return distance; + +} + + +bool AudioEventMatcher::checkMatch(const double& recordedPitch, const double& livePitch){ + if (abs(recordedPitch - livePitch) < 40) + return true; + else + return false; +} + + void AudioEventMatcher::windowResized(const int& w, const int& h){ recordedTracks.windowResized(w,h); -} \ No newline at end of file + bayesTempoWindow.resized(w,h); + bayesPositionWindow.resized(w,h); +} + + + +void AudioEventMatcher::updateBayesianDistributions(const double& newEventTime){ + //MOVE INTO bayesianStruct?? XX + + + + //NEED TO CHECK HERE THAT THEY HAVE THE SAME OFFSETS + bayesianStruct.prior.copyFromDynamicVector(bayesianStruct.posterior);//try the otehr way + + //bayesianStruct.copyPriorToPosterior(); + //need to get new MAP position and set the offset of the arrays + //currently bestEstimate is the approx for the new MAP position + + double timeDifference = newEventTime - bayesianStruct.lastEventTime; + printf("updating distributions at time %f diff %f\n", newEventTime, timeDifference); + + //addnoise to the tempo distribution + //bayesianStruct.decaySpeedDistribution(timeDifference); + + if (timeDifference > 50){ + bayesianStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10.0 / 100.); + } + + bayesianStruct.updateBestEstimate(timeDifference); + + bayesianStruct.lastBestEstimateUpdateTime = newEventTime;//getTimeNow(timePlayed); + + bayesianStruct.setNewDistributionOffsets(max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2))); + + bayesianStruct.crossUpdateArrays(bayesianStruct.posterior, bayesianStruct.relativeSpeedPosterior, timeDifference); + + bayesianStruct.posterior.offset = max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2));// bayesianStruct.prior.offset = max(0., bayesianStruct.bestEstimate - (bayesianStruct.prior.scalar*bayesianStruct.prior.arraySize/2)); + + bayesianStruct.lastEventTime = newEventTime;//bayesianStruct.lastEventTime = ofGetElapsedTimeMillis(); +}