diff aubioOnsetDetectorOFvisualiser/src/testApp.cpp @ 3:979125db34ab

added OF visualiser src code. Added a long term median trigger threshold. New method is working very well on onsets
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 21 Nov 2011 23:22:40 +0000
parents
children fb106f14e0a4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/aubioOnsetDetectorOFvisualiser/src/testApp.cpp	Mon Nov 21 23:22:40 2011 +0000
@@ -0,0 +1,423 @@
+#include "testApp.h"
+//#include "math.h" 
+
+#define SAMPLING_FREQUENCY 44100
+#define FOURIER_LENGTH 2048
+#define TEXT_HEIGHT 10
+//--------------------------------------------------------------
+void testApp::setup(){
+	// listen on the given port
+//	cout << "listening for osc messages on port " << PORT << "\n";
+	receiver.setup( PORT );
+
+	current_msg_string = 0;
+	mouseX = 0;
+	mouseY = 0;
+	mouseButtonState = "";
+
+	ofBackground( 30, 30, 130 );
+
+
+	outputGraphics = false;
+	
+	maximumDetectionFunction = 20;
+	minimumDetectionFunction = -20;
+	
+	screenWidth = (float) ofGetWidth();
+	screenHeight = (float) ofGetHeight();
+	
+	mouseDownX = 0;
+	mouseDownY = 0;
+	
+	amplitudeNumber = 256;//number of amplitudes shown on screen
+		
+	maxValue = 1.0;
+	
+	detectionType = "complex";
+	lastOnsetDetectionValue;
+	
+	logMode = false;
+	
+	midiMode = true;
+	
+	resetMaxima = false;
+	
+	reIndexFlag = false;
+
+	ofBackground(0,0,0);
+	
+	rawOnsetIndex = 0;
+}
+
+//--------------------------------------------------------------
+void testApp::update(){
+maxValue *= 0.995;
+	// hide old messages
+
+	// check for waiting messages
+	while( receiver.hasWaitingMessages() )
+	{
+		// get the next message
+		ofxOscMessage m;
+		receiver.getNextMessage( &m );
+
+			// unrecognized message: display on the bottom of the screen
+	//		string msg_string;
+	//		msg_string = m.getAddress();
+			if (m.getAddress() == "/aubioData" ){
+			
+				if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){
+				
+				onsetIndex++;
+				onsetRecorded[onsetIndex] = false;
+				
+					if (onsetIndex >= NUM_DETECTION_SAMPLES)
+					onsetIndex = 0;
+				
+				onsetFunction[onsetIndex] =  m.getArgAsFloat(0);
+				
+				checkMaxima(m.getArgAsFloat(0));
+				
+				}//end if type FLOAT
+			}//end if aubioData
+			
+					
+	if (m.getAddress() == "/rawAubioData" ){
+			
+				if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){
+				
+				rawOnsetIndex++;
+						
+					if (rawOnsetIndex >= NUM_DETECTION_SAMPLES)
+					rawOnsetIndex = 0;
+				
+				rawOnsetFunction[rawOnsetIndex] =  m.getArgAsFloat(0);
+				checkRawMaxima(m.getArgAsFloat(0));
+				
+				}//end if type FLOAT
+			}//end spec diff message
+
+
+		if (m.getAddress() == "/medianAubioData" ){
+			
+			if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){
+				
+				medianOnsetIndex++;
+				
+				if (medianOnsetIndex >= NUM_DETECTION_SAMPLES){
+					medianOnsetIndex = 0;
+				}
+				
+				if(medianOnsetIndex > 0)
+				medianOnsetRecorded[medianOnsetIndex] = false;//but how do we know this happens first!
+				
+				medianOnsetFunction[medianOnsetIndex] =  m.getArgAsFloat(0);
+				
+			}//end if type FLOAT
+		}//end spec diff message
+		
+		
+		
+
+		if (m.getAddress() == "/onset" ){
+			onsetRecorded[onsetIndex] = true;
+			lastOnsetDetectionValue = onsetFunction[onsetIndex];
+		}
+
+		if (m.getAddress() == "/medianOnset" ){
+			medianOnsetRecorded[onsetIndex] = true;
+		}
+
+		
+		
+		if (m.getAddress() == "/rawOnset" ){
+			rawOnsetRecorded[rawOnsetIndex] = true;
+
+		}
+
+		if (m.getAddress() == "/mode" ){
+		resetMaxima = true; 
+		detectionType = m.getArgAsString(0);
+		}
+
+	}//end while
+
+}
+
+
+void testApp::checkMaxima(float f){
+
+//maximumDetectionFunction *= 0.99999;
+//minimumDetectionFunction += (maximumDetectionFunction - minimumDetectionFunction)*0.00001;
+
+	if (maximumDetectionFunction * 1.08 < f){
+		maximumDetectionFunction = 1.08*f;
+	}
+
+	if (minimumDetectionFunction + (fabs(minimumDetectionFunction * 0.08)) > f){
+		minimumDetectionFunction = f - (0.08 * fabs(f));
+	}
+	
+	if (resetMaxima == true){
+			maximumDetectionFunction = 30;
+			minimumDetectionFunction = 0;
+			resetMaxima = false;
+			}
+	
+}
+
+
+void testApp::checkRawMaxima(float f){
+
+//maximumDetectionFunction *= 0.99999;
+//minimumDetectionFunction += (maximumDetectionFunction - minimumDetectionFunction)*0.00001;
+
+	if (maximumDetectionFunction * 1.08 < f){
+		maximumDetectionFunction = 1.08*f;
+	}
+
+	if (minimumDetectionFunction + (fabs(minimumDetectionFunction * 0.08)) > f){
+		minimumDetectionFunction = f - (0.08 * fabs(f));
+	}
+
+}
+
+
+
+//--------------------------------------------------------------
+void testApp::draw(){
+
+	drawOnsetFunction();
+	printInfo();
+
+}
+
+void testApp::printMessages(){
+	string buf;
+	buf = "listening for osc messages on port" + ofToString( PORT );
+	ofDrawBitmapString( buf, 10, 20 );
+
+	for ( int i=0; i<NUM_MSG_STRINGS; i++ )
+	{
+	ofDrawBitmapString( msg_strings[i], 10, 40+15*i );
+	}
+	
+}
+
+void testApp::printInfo(){	
+	ofSetColor(255,255,255);
+	string printString;
+
+/*	printString = "Max ";
+	printString += ofToString(maximumDetectionFunction);
+	printString += "    Min ";
+	printString += ofToString(minimumDetectionFunction);
+*/	
+
+	printString += detectionType;
+	printString +="    ";
+	printString += ofToString(lastOnsetDetectionValue, 1);
+	ofDrawBitmapString( printString  , 10, ofGetHeight() - 20);
+}
+
+//--------------------------------------------------------------
+void testApp::keyPressed  (int key){
+
+	if (key == OF_KEY_UP){
+
+	}
+
+	if (key == OF_KEY_DOWN ){
+
+	}		
+
+
+	if (key == OF_KEY_RIGHT ){
+
+	}		
+
+	if (key == OF_KEY_LEFT ){
+
+	}		
+
+	if (key == 'L' || key == 'l'){
+	logMode = !logMode;
+	}
+
+	if (key == 'p' || key == 'P'){
+
+	}
+
+	if (key == 'm' || key == 'M'){
+	midiMode = !midiMode;
+	}
+		
+	if (key == 'x' || key == 'X'){
+	amplitudeNumber *= 2;
+	}
+
+	if (key == 'z' || key == 'Z'){
+	amplitudeNumber /= 2;
+	}
+
+if ((key == '=' || key == '+') && amplitudeNumber < 120){
+	amplitudeNumber += 8;
+	}
+
+if ((key == '-' || key == '_') && amplitudeNumber > 12){
+	amplitudeNumber -= 8;
+	}		
+
+}
+
+
+
+void testApp::drawOnsetFunction(){
+	int tmpIndex = onsetIndex;
+	float width = screenWidth / (float) amplitudeNumber;	
+	float maximumValue = maximumDetectionFunction ;
+	float minimumValue = minimumDetectionFunction ;
+	float difference = maximumValue - minimumValue;
+	float scale_factor = screenHeight/ difference;
+	
+	//draw axis
+	ofSetColor(255,255,255);
+	ofLine(0, screenHeight - (scale_factor*(0 - minimumValue)), 
+			(int) (width*(amplitudeNumber)),  screenHeight - (scale_factor*(0 - minimumValue)) );
+
+	
+	for (int Xvalue = 0;Xvalue < amplitudeNumber; Xvalue++){
+	
+	int Xindex = (onsetIndex-Xvalue) ;
+	int previousIndex = (Xindex-1);
+	
+	ofSetColor(55,100,255);
+
+	ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(onsetFunction[previousIndex]- minimumValue)), 
+			(int) (width*(amplitudeNumber - Xvalue)),  screenHeight - (scale_factor*(onsetFunction[Xindex]- minimumValue)) );
+
+	if (onsetRecorded[Xindex] == true){
+		ofSetColor(255,100,255);
+		ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(onsetFunction[Xindex]- minimumValue)) , 3);
+	}
+	
+//specDiffOnsets	
+	ofSetColor(55,100,55);
+ Xindex = (rawOnsetIndex-Xvalue) ;
+ previousIndex = (Xindex-1);
+
+	ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(rawOnsetFunction[previousIndex]- minimumValue)), 
+			(int) (width*(amplitudeNumber - Xvalue)),  screenHeight - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) );
+	
+		//median of Onset fn	
+		ofSetColor(205,0,0);
+		Xindex = (medianOnsetIndex-Xvalue) ;
+		previousIndex = (Xindex-1);
+		
+		ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(medianOnsetFunction[previousIndex]- minimumValue)), 
+			   (int) (width*(amplitudeNumber - Xvalue)),  screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) );
+		
+		
+
+	if (rawOnsetRecorded[Xindex] == true){
+		ofSetColor(255,100,0);
+		ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) , 3);
+	}
+		
+		if (medianOnsetRecorded[Xindex] == true){
+			ofSetColor(255,0,0);
+			ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 3);
+		}
+		
+		
+		/*
+	if (medianOnsetRecorded[Xindex] == true){
+		ofSetColor(255,0,0);
+		ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 3);
+	}	
+	*/
+		ofSetColor(255,100,0);
+		
+	}//end for Xvalue (across the recent observations of osc data)
+
+	
+	//label y axis
+	int axisHeight, stepSize;
+	ofSetColor(255,255,255);
+	stepSize = 1000;
+
+	while((difference / stepSize) < 3)
+	stepSize /= 2;
+	
+	while ((difference / stepSize) > 7)// maximum 6 numbers to display
+	stepSize *= 2;
+
+	
+	for (axisHeight = 0; axisHeight < maximumDetectionFunction; axisHeight += stepSize){
+	ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50,
+	 (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) );
+	}
+	
+	for (axisHeight = max(0, (int)minimumDetectionFunction); axisHeight > min(0, (int)minimumDetectionFunction); axisHeight -= stepSize){
+	ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50,
+	 (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) );
+	}
+	
+	//label x axis
+	stepSize = 20;//need to make sure not too many of these:
+	
+	while((amplitudeNumber / stepSize) < 4)
+	stepSize /= 2;
+	
+	while ((amplitudeNumber / stepSize) > 8)
+	stepSize *= 2;
+
+	int labelIndex = onsetIndex - (onsetIndex % stepSize);
+	for (int y = labelIndex; y > onsetIndex - amplitudeNumber; y -= stepSize){
+		ofDrawBitmapString( ofToString((int)y), (int) (width*(amplitudeNumber - (onsetIndex - y))),
+	 (int) ((TEXT_HEIGHT+2) + (screenHeight - (scale_factor*(0 - minimumValue)))) );
+	}
+	
+}//end label 
+//--------------------------------------------------------------
+void testApp::mouseMoved(int x, int y ){
+
+
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseDragged(int x, int y, int button){
+if ((x - mouseDownX) > 50 ){
+mouseDownX = x;
+}
+
+if ((x - mouseDownX) < -50){
+
+mouseDownX = x;
+}
+
+
+}
+
+//--------------------------------------------------------------
+void testApp::mousePressed(int x, int y, int button){
+
+mouseDownX = x;
+mouseDownY = y;
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::windowResized(int w, int h){
+
+	screenWidth = (float) ofGetWidth();
+	screenHeight = (float) ofGetHeight();
+	
+}
+