changeset 2:179c09199b3c

bayesian vector now adding gaussians for kick onsets
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 31 Jan 2012 21:34:19 +0000
parents 852173ca8365
children 5e188c0035b6
files README.txt bayesianArraySrc/DynamicVector.cpp bayesianArraySrc/DynamicVector.h src/AudioEventMatcher.cpp src/AudioEventMatcher.h src/RecordedMultitrackAudio.cpp src/RecordedMultitrackAudio.h src/testApp.cpp
diffstat 8 files changed, 148 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/README.txt	Tue Jan 31 17:35:30 2012 +0000
+++ b/README.txt	Tue Jan 31 21:34:19 2012 +0000
@@ -9,3 +9,9 @@
 ofxSoundfileloader
 ofxAubioOnsetDetector
 
+
+
+Possible MIDI JNMR
+
+when adding gaussians - need to convert to the matrix indices - currently not done??
+
--- a/bayesianArraySrc/DynamicVector.cpp	Tue Jan 31 17:35:30 2012 +0000
+++ b/bayesianArraySrc/DynamicVector.cpp	Tue Jan 31 21:34:19 2012 +0000
@@ -157,6 +157,26 @@
 	//now delete tmp array
 }
 
+
+
+void DynamicVector::addGaussianShapeFromRealTime(const double& actualTime, const double& StdDev, double factor){
+	
+	double mean = getRealTermsAsIndex(actualTime);
+	printf("Gaussian realtime %f at index %f\n", actualTime, mean);
+	int i;
+	double std_dev_factor = (2*StdDev*StdDev);
+	factor *= (1/(StdDev*sqrt(2*PI)));
+	int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev));
+	int minVal = max(0, (int)(mean - 4.8*StdDev));
+	
+	for (i=minVal;i < maxVal;i++){
+		array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor));
+	}
+	
+	//	addGaussianShapeByLookupTable(mean, StdDev, factor);
+}
+
+
 void DynamicVector::addGaussianShape(const double& mean, const double& StdDev, double factor){
 	
 	int i;
--- a/bayesianArraySrc/DynamicVector.h	Tue Jan 31 17:35:30 2012 +0000
+++ b/bayesianArraySrc/DynamicVector.h	Tue Jan 31 21:34:19 2012 +0000
@@ -43,6 +43,11 @@
 
 	void addConstant(const double& value);
 	void addGaussianShape(const double& mean, const double& stddev, double factor);
+	
+	void addGaussianShapeFromRealTime(const double& actualTime, const double& StdDev, double factor);
+		
+
+		
 	void addTriangularShape(double mean, double width, double factor);
 	void addToIndex(const int& index, const double& constant);
 	
--- a/src/AudioEventMatcher.cpp	Tue Jan 31 17:35:30 2012 +0000
+++ b/src/AudioEventMatcher.cpp	Tue Jan 31 21:34:19 2012 +0000
@@ -10,7 +10,7 @@
 #include "AudioEventMatcher.h"
 
 
-const int matchWindowWidth = 1200;
+const int matchWindowWidth = 6000;
 
 AudioEventMatcher::AudioEventMatcher(){
 
@@ -36,14 +36,66 @@
 	//ofRect(20, 20, 300, 200);
 	
 	recordedTracks.drawTracks();
-	bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow);
+	
+	ofSetColor(255);
+//	bayesianStruct.relativeSpeedPrior.drawVector(0, 200, bayesTempoWindow);
+	
+	double screenWidthMillis = recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.framesToMillis(recordedTracks.loadedAudioFiles[0].fileLoader.onsetDetect.amplitudeNumber);
+	
+	
+	bayesianStruct.likelihood.drawVector(0, screenWidthMillis, bayesTempoWindow);
 	
 }
 
 
 void AudioEventMatcher::newPitchEvent(const double& pitchIn, const double& timeIn){
 	liveInput.addPitchEvent(pitchIn, timeIn);
-	//matchNewPitchEvent();
+	recordedTracks.matchNewPitchEvent(0, pitchIn, timeIn);
+}
+
+void AudioEventMatcher::newKickEvent(const double& timeIn){
+	matchNewOnsetEvent(0, timeIn);
+}
+
+
+void AudioEventMatcher::newSnareEvent(const double& timeIn){
+	matchNewOnsetEvent(0, timeIn);
+}
+
+//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 likelihoodWidth = 40;
+	
+	bayesianStruct.likelihood.offset = bayesianStruct.prior.offset;
+	bayesianStruct.likelihood.zero();//set to zero
+	
+	double quantity = 1;//likelihoodToNoiseRatio / numberOfMatches;
+	int numberOfMatchesFound = 0;
+
+	
+	double startTime = bayesianStruct.likelihood.offset;
+	double endTime = bayesianStruct.likelihood.offset + matchWindowWidth;
+	
+	if (channel <= recordedTracks.numberOfAudioTracks){
+		for (int i = 0;i < recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){
+			double millisTime = recordedTracks.loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].millisTime;
+			if (millisTime >= startTime && millisTime <= endTime){
+				bayesianStruct.likelihood.addGaussianShapeFromRealTime(millisTime, likelihoodWidth,  quantity);
+				numberOfMatchesFound++;
+				printf("Adding Gaussian for onset at time %f offset %f\n", millisTime, bayesianStruct.likelihood.offset);
+				
+			}
+		}
+	}
+	
+	bayesianStruct.likelihood.renormalise();
+	
+	//bayesStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesStruct.likelihood.length);
+	
+	
 }
 
 
--- a/src/AudioEventMatcher.h	Tue Jan 31 17:35:30 2012 +0000
+++ b/src/AudioEventMatcher.h	Tue Jan 31 21:34:19 2012 +0000
@@ -30,6 +30,11 @@
 	void draw();
 	
 	void newPitchEvent(const double& pitchIn, const double& timeIn);
+	void newKickEvent(const double& timeIn);
+	void newSnareEvent(const double& timeIn);
+	
+	void matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn);
+	void matchNewOnsetEvent(const int& channel, const double& timeIn);
 	
 	BayesianArrayStructure bayesianStruct;//hold the probability distriubtions
 	
--- a/src/RecordedMultitrackAudio.cpp	Tue Jan 31 17:35:30 2012 +0000
+++ b/src/RecordedMultitrackAudio.cpp	Tue Jan 31 21:34:19 2012 +0000
@@ -13,7 +13,7 @@
 void RecordedMultitrackAudio::loadTestAudio(){
 	
 	
-	const char	*infilename = "../../../data/sound/bach4_short1.wav";	
+	const char	*infilename = "../../../data/sound/basicClavScale.wav";	
 	
 	//LoadedAudioHolder lah;
 	//	lah.loadAudioFile(infilename);
@@ -23,12 +23,13 @@
 	//but not then delete the instance before the vector of all audio tracks has been used
 	//the above code using lah has problem that it deletes objects once out of the scope of testApp.setup()
 	//when lah is in theory no longer used - something like that possible? - at least pointers to onset detection seem deleted
-	loadedAudioPtr = new LoadedAudioHolder;
+	loadedAudioPtr = new LoadedAudioHolder();
 	loadedAudioPtr->loadAudioFile(infilename);
 	//	loadedAudioFiles.push_back(*loadedAudioPtr);
 	loadedAudioFiles[0] = *loadedAudioPtr;
 	
 	loadedAudioFiles[0].fileLoader.onsetDetect.window.setToRelativeSize(0, 0.0, 1, 0.25);
+	loadedAudioFiles[0].setTrackType(0);//	fileLoader.onsetDetect.trackType = 0;
 	
 	//	printf("Loaded audio %i\n", (int)numberOfAudioTracks);
 	printf("loaded max val  is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue);
@@ -36,11 +37,15 @@
 	printf("BEFORE LOADING 1\n");
 	printInfo();
 	
+	infilename = "../../../data/sound/basicClavScale2.wav";	
+	
 	loadedAudioPtr = new LoadedAudioHolder;
 	loadedAudioPtr->loadAudioFile(infilename);
 	//	loadedAudioFiles.push_back(*loadedAudioPtr);
 	loadedAudioFiles[1] = *loadedAudioPtr;
 	loadedAudioFiles[1].fileLoader.onsetDetect.window.setToRelativeSize(0, 0.3, 1, 0.25);
+	loadedAudioFiles[1].setTrackType(1);
+//	loadedAudioFiles[1].fileLoader.onsetDetect.trackType = 0;
 	
 	printf("AFTER LOADING 1\n");
 	printInfo();
@@ -57,6 +62,8 @@
 	for (int i = 0;i < numberOfAudioTracks;i++){		
 		loadedAudioFiles[i].draw();
 	}
+	
+	ofDrawBitmapString("pitch "+ofToString(recentPitch, 2), 20, 20);
 }
 
 
@@ -66,6 +73,33 @@
 }
 
 
+void RecordedMultitrackAudio::matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn){
+	//start at beginning but OPTIMISE later
+	
+	if (channel <= numberOfAudioTracks){
+		for (int i = 0;i < loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets.size();i++){
+			
+			if (checkMatch(loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].aubioPitch, pitchIn)) {
+				 loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = true;
+			 } 
+			 else{
+				 loadedAudioFiles[channel].fileLoader.onsetDetect.chromaOnsets[i].matched = false;
+			 }
+			
+		 }
+	}
+	
+	recentPitch = pitchIn;
+}
+
+bool RecordedMultitrackAudio::checkMatch(const double& recordedPitch, const double& livePitch){
+	if (abs(recordedPitch - livePitch) < 40)
+		return true;
+	else
+		return false;
+}
+
+
 void RecordedMultitrackAudio::switchScreens(){
 	for (int i = 0;i < numberOfAudioTracks;i++)
 		loadedAudioFiles[i].switchScreens();
--- a/src/RecordedMultitrackAudio.h	Tue Jan 31 17:35:30 2012 +0000
+++ b/src/RecordedMultitrackAudio.h	Tue Jan 31 21:34:19 2012 +0000
@@ -43,9 +43,16 @@
 	void zoomOut();
 	
 	
+	void matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn);
+
+	bool checkMatch(const double& recordedPitch, const double& livePitch);
+	
+	double recentPitch;
 	//variables
 	int numberOfAudioTracks;
 	LoadedAudioHolder* loadedAudioPtr;
 	LoadedAudioHolder loadedAudioFiles[5];
+	
+	
 };
 #endif
\ No newline at end of file
--- a/src/testApp.cpp	Tue Jan 31 17:35:30 2012 +0000
+++ b/src/testApp.cpp	Tue Jan 31 21:34:19 2012 +0000
@@ -99,6 +99,20 @@
 			printf("AUBIO PITCH RECEIVED %f at time %i\n", pitchIn, timeIn);
 			eventMatcher.newPitchEvent(pitchIn, timeIn);
 		}
+		
+		if ( m.getAddress() == "/kick" ){
+		//	float pitchIn = m.getArgAsFloat(0); 
+			double timeIn = m.getArgAsInt32(0); 
+			printf("kick RECEIVED at time %f\n", timeIn);
+			eventMatcher.newKickEvent(timeIn);
+		}
+		
+		if ( m.getAddress() == "/snare" ){
+			//	float pitchIn = m.getArgAsFloat(0); 
+			double timeIn = m.getArgAsInt32(0); 
+			printf("snare RECEIVED at time %f\n", timeIn);
+			eventMatcher.newSnareEvent(timeIn);
+		}
 	}
 }