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();
+}