Mercurial > hg > aubio-onset-detector
view 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 source
#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(); }