changeset 26:179365726f07

live input, calculates score rating
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sun, 04 Dec 2011 00:02:26 +0000
parents 2a025ea7c793
children fa1890efa044
files hackday/MidiInputStream.cpp hackday/MidiInputStream.h hackday/midiEventHolder.cpp hackday/midiEventHolder.h hackday/testApp.cpp hackday/testApp.h
diffstat 6 files changed, 135 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/hackday/MidiInputStream.cpp	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/MidiInputStream.cpp	Sun Dec 04 00:02:26 2011 +0000
@@ -16,10 +16,17 @@
 
 
 void MidiInputStream::reset(){
+
 	midiInputEvents.clear();
+	midiInputTimes.clear();
+	
 	eventTimesForNote.clear();
 	eventTimesForNote.assign (127, 0.0);
-	midiInputTimes.clear();
+
+	
+	totalNotesRecievedByPitch.clear();
+	totalNotesRecievedByPitch.assign (127, 0);
+	
 }
 
 bool MidiInputStream::noteInReceived(ofxMidiEventArgs &args){
@@ -37,13 +44,13 @@
 			//	printf("volume is %i\n", args.byteTwo);
 				double time = ofGetElapsedTimeMillis();
 				eventTimesForNote[newPitch] = time;
-				
 				noteOn = true;
+				newNoteCounted(newPitch);
 				
 			}else{
 				double time = ofGetElapsedTimeMillis();
 				time -= eventTimesForNote[newPitch];
-			//	printf(", OFF after %f millis %f ticks\n", time, time * (*factor));
+			//	printf(", NOTE OFF after %f millis %f ticks\n", time, time * (*factor));
 				
 				int index = endNote(newPitch);
 				//correct the length of note time
@@ -60,6 +67,9 @@
 	//cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << newPitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl;
 }
 
+void  MidiInputStream::newNoteCounted(const int& pitch){
+	totalNotesRecievedByPitch[pitch] += 1;
+}
 
 int MidiInputStream::endNote(int notePitch){
 	int index = midiInputEvents.size()-1;
@@ -70,10 +80,29 @@
 	return index;
 }
 
+double MidiInputStream::calculateTotalScore(midiEventHolder& midiEvents){
+	double gameScore = 1.0;
+	double totalNotes = 1.0;
+	if (totalNotesRecievedByPitch.size() > 100){
+		for (int i = 30;i < 90;i++){
+			gameScore += abs(totalNotesRecievedByPitch[i] - midiEvents.recordedTotalNoteCounterByPitch[i]);
+			totalNotes += midiEvents.recordedTotalNoteCounterByPitch[i];
+		}
+	}
+	return 1.0 - (gameScore / totalNotes);
+
+}
+
 void MidiInputStream::printNotes(){
 	printf("live input \n");
 	for (int i = 0;i < midiInputEvents.size();i++){
 		printf("ticktime %i :: pitch %i @ millis %f\n",  midiInputEvents[i][0],  midiInputEvents[i][1],  midiInputTimes[i]);
 	}
 }
+
+void MidiInputStream::printTotalCount(){
+	for (int i = 0;i < totalNotesRecievedByPitch.size();i++){
+		printf("LIVE PLAYED TOTAL[%i] := %i\n", i, totalNotesRecievedByPitch[i]);
+	}
+}
 	
--- a/hackday/MidiInputStream.h	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/MidiInputStream.h	Sun Dec 04 00:02:26 2011 +0000
@@ -32,10 +32,15 @@
 	typedef std::vector<double> DoubleVector;
 	DoubleVector eventTimesForNote;
 	
+	double calculateTotalScore(midiEventHolder& midiEvents);
+	
 	IntMatrix midiInputEvents;
 	DoubleVector midiInputTimes;
 	IntVector v;
-
+	IntVector totalNotesRecievedByPitch;
+	void newNoteCounted(const int& pitch);
+	void printTotalCount();
+	
 	double* startTime;
 	midiEventHolder* eventHolder;
 	
--- a/hackday/midiEventHolder.cpp	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/midiEventHolder.cpp	Sun Dec 04 00:02:26 2011 +0000
@@ -20,7 +20,7 @@
 	runningInRealTime = true;
 	bayesStruct.realTimeMode = &runningInRealTime;
 	
-	minimumMatchSpeed = 0.5;
+	minimumMatchSpeed = 0.2;
 	maximumMatchSpeed = 2.0;
 	minimumTimeIntervalForTempoUpdate = 150;
 	
@@ -90,6 +90,11 @@
 	matchMatrix.clear();
 	bestMatchIndex = 0;
 	
+	recordedTotalNoteCounterByPitch.clear();
+	recordedTotalNoteCounterByPitch.assign(127,0);
+	totalNoteCounterIndex = 0;
+	
+	
 	bayesStruct.resetSpeedToOne();
 	bayesStruct.setSpeedPrior(speedPriorValue);
 	setMatchedNotesBackToFalse();
@@ -111,6 +116,10 @@
 	playedNoteOnMatrix.clear();
 	matchMatrix.clear();
 	bestMatchFound.clear();
+	
+	recordedTotalNoteCounterByPitch.clear();
+	recordedTotalNoteCounterByPitch.assign(127, 0);
+	totalNoteCounterIndex = 0;
 }
 
 void midiEventHolder::printNotes(){
@@ -624,6 +633,16 @@
 	if (runningInRealTime)
 	bayesStruct.updateBestEstimate(timeDifference);
 	
+	updateNoteCounter();
+	
+}
+
+void  midiEventHolder::updateNoteCounter(){
+	while (totalNoteCounterIndex < bestMatchIndex){
+		int tmpPitch = recordedNoteOnMatrix[totalNoteCounterIndex][1];
+		recordedTotalNoteCounterByPitch[tmpPitch] += 1;
+		totalNoteCounterIndex++;
+	}
 }
 
 
@@ -946,6 +965,8 @@
 }
 
 
+
+
 void midiEventHolder::correctTiming(IntMatrix& noteOnMatrix){
 	
 	if (noteOnMatrix.size() > 0 && noteOnMatrix[0][0] < 0) {
@@ -956,3 +977,10 @@
 	}
 
 }
+
+
+void midiEventHolder::printNoteCounter(){
+	for (int i = 0;i < recordedTotalNoteCounterByPitch.size();i++){
+		printf("RECORDED TOTAL[%i] := %i", i, recordedTotalNoteCounterByPitch[i]);
+	}
+}
\ No newline at end of file
--- a/hackday/midiEventHolder.h	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/midiEventHolder.h	Sun Dec 04 00:02:26 2011 +0000
@@ -46,6 +46,9 @@
 	IntVector bestMatchFound;
 	IntVector measureVector;
 	
+	IntVector recordedTotalNoteCounterByPitch;
+	int totalNoteCounterIndex;
+	
 	DoubleMatrix matchConfidence;
 	double totalConfidence;
 	
@@ -83,6 +86,8 @@
 	
 	void printMatchMatrix();
 	void printRecordedEvents();
+	void printNoteCounter();
+	void updateNoteCounter();
 	
 	void setMatchLikelihoods(int numberOfMatches);
 	
--- a/hackday/testApp.cpp	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/testApp.cpp	Sun Dec 04 00:02:26 2011 +0000
@@ -13,7 +13,7 @@
 	midiIn.listPorts();
 	midiIn.openPort(2);
 	
-	transpose = 24;
+	transpose = 12;
 	noteInStream.transposeVal = &transpose;
 	
 	noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events
@@ -47,6 +47,7 @@
 	
 	midiEvents.ticksPerScreen += 4000;
 	lastScoreIndexSent = 0;
+	performanceRating = 1.0;
 	
 }
 
@@ -65,12 +66,14 @@
 		
 		if ( m.getAddress() == "/midinoteon" )
 		{
-			int newMidiOnPitch = m.getArgAsInt32(0);
+			int newMidiOnPitch = m.getArgAsInt32(0) + transpose;
 			int velocity = m.getArgAsInt32(1);
 			double time = m.getArgAsFloat(2);
 			
-			if (velocity != 0)
-			midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
+			if (velocity != 0){
+				midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
+				noteInStream.newNoteCounted(newMidiOnPitch);
+			}
 
 		}
 		
@@ -155,24 +158,50 @@
 	}
 	if (lastMeasureSent != tmpMeasure){
 	sendMeasureToMuseScore();
+	performanceRating =	noteInStream.calculateTotalScore(midiEvents);
 	}
 	
 
 }
 
+void testApp::sendBlackNotes(){
+	ofxOscMessage m;
+	m.setAddress( "/plugin" );
+	string noteString;	
+	noteString = "blacknotes.js";
+	m.addStringArg( noteString);
+	sender.sendMessage( m ); 
+}
+
 void testApp::sendNoteToMuseScore(){
 	int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0];
 	int pitch = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][1];
 	printf("sending to muse score %i, %i \n", ticks, pitch);
 		
-		   ofxOscMessage m;
-		   m.setAddress( "/plugin" );
+	/*
+		ofxOscMessage m;
+		m.setAddress( "/plugin" );
+		string noteString;	
+		noteString = "blackNotes.js";
+		m.addStringArg( noteString);
+		sender.sendMessage( m ); 
+	*/
+	 
+			ofxOscMessage m;
+			m.setAddress( "/plugin" );
+			string noteString;	
+			noteString = "coloronenote.js";
+			noteString += ",myTick,"+ofToString(ticks)+",myPitch,"+ofToString(pitch);
+		//	printf("%s\n", noteString);
+			m.addStringArg( noteString);
+			sender.sendMessage( m ); 
+	/*
 		   m.addStringArg( "coloronenote.js" );
 		   m.addStringArg("mytick");
 		   m.addIntArg( ticks );
 		   m.addStringArg("mypitch");
 		   m.addIntArg( pitch);
-		   sender.sendMessage( m );  
+	*/	   
 		   
 	//	   /plugin coloronenote.js mytick 100 mypitch 56;
 }
@@ -239,6 +268,7 @@
 	ofDrawBitmapString(info, 20, 20);
 	midiEvents.drawMidiFile(noteInStream.midiInputEvents);
 
+	ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 20, 50);
 }
 
 //--------------------------------------------------------------
@@ -261,6 +291,12 @@
 		timenow += ofGetElapsedTimeMillis();
 		printf("CROSS UPDATE TOOK %f", timenow);
 	}
+
+	if (key == OF_KEY_LEFT){
+		
+	}
+	
+	if (key == OF_KEY_RIGHT)
 	
 	if (key == OF_KEY_RETURN)
 		stopPlaying();
@@ -276,6 +312,10 @@
 //		midiEvents.findMatch(84, 0, 10000);
 	}
 	
+	if (key == 'b'){
+		sendBlackNotes();
+	}
+	
 	if (key == OF_KEY_DOWN){
 		if (midiEvents.ticksPerScreen >= 4000)
 		midiEvents.ticksPerScreen -= 2000;
@@ -307,6 +347,11 @@
 		noteInStream.reset();
 		liveInputPlaying = false;
 		stopPlaying();
+		lastMeasureSent = 0;
+		sendMeasureToMuseScore();
+		sendBlackNotes();
+		lastScoreIndexSent = 0;
+		
 	}
 	
 	if (key == 'o'){
@@ -362,17 +407,24 @@
 void testApp::startPlaying(){
 	playing = !playing;
 	midiEvents.reset();
+	noteInStream.reset();
 	midiEvents.setStartPlayingTimes();
-	
+	sendBlackNotes();
 	//this is where we stop and start playing
 }
 
 void testApp::stopPlaying(){
+	midiEvents.printNoteCounter();
+	noteInStream.printTotalCount();
+	noteInStream.calculateTotalScore(midiEvents);
+	
+	
 	playing = false;
 	liveInputPlaying = false;
 	lastScoreIndexSent = 0;
 	midiEvents.bestMatchIndex = 0;
 	sendNoteToMuseScore();
+	
 }
 
 bool testApp::getFilenameFromDialogBox(string* fileNameToSave){
--- a/hackday/testApp.h	Sat Dec 03 21:09:13 2011 +0000
+++ b/hackday/testApp.h	Sun Dec 04 00:02:26 2011 +0000
@@ -88,7 +88,9 @@
 	void checkNewScoreNote();
 	void sendNoteToMuseScore();
 	void sendMeasureToMuseScore();
+	void sendBlackNotes();
 	void findMeasure();
+	
 	// midi addon
 	ofxMidiIn	midiIn;
 	// this is your listener function
@@ -102,6 +104,7 @@
 	int transpose;
 	int lastScoreIndexSent;
 	int lastMeasureSent;
+	double performanceRating;
 private:
 	ofxOscReceiver	receiver;
 	ofxOscSender	sender;