diff options
| author | Comment <tim@gray.(none)> | 2013-05-21 01:06:38 +0100 |
|---|---|---|
| committer | Comment <tim@gray.(none)> | 2013-05-21 01:06:38 +0100 |
| commit | e453cc17916908104467875db31e3fa08817cce1 (patch) | |
| tree | 4f89f8d0b1d2cad4b5ffd1ec7607a846c26dedfd | |
| parent | cb7ec4965e6ec3d2142522c5c110b240f800e55d (diff) | |
vamphost
| -rwxr-xr-x | vamphost/config.make | 4 | ||||
| -rw-r--r-- | vamphost/src/main.cpp | 2 | ||||
| -rw-r--r-- | vamphost/src/ofxVamphost.cpp | 45 | ||||
| -rw-r--r-- | vamphost/src/ofxVamphost.h | 6 | ||||
| -rw-r--r-- | vamphost/src/testApp.cpp | 182 | ||||
| -rw-r--r-- | vamphost/src/testApp.h | 15 |
6 files changed, 215 insertions, 39 deletions
diff --git a/vamphost/config.make b/vamphost/config.make index a4db95a..da65b3e 100755 --- a/vamphost/config.make +++ b/vamphost/config.make @@ -11,14 +11,14 @@ OF_ROOT = /home/tim/workspace/openFrameworks # for example search paths like: # USER_CFLAGS = -I src/objects -USER_CFLAGS = -I $(OF_ROOT)/addons/ofxOpenNI/include/openni -I $(OF_ROOT)/addons/ofxOpenNI/include/nite -I $(OF_ROOT)/addons/ofxOpenNI/src +USER_CFLAGS = -fpermissive # USER_LDFLAGS allows to pass custom flags to the linker # for example libraries like: # USER_LDFLAGS = libs/libawesomelib.a -USER_LDFLAGS = -lvamp-hostsdk +USER_LDFLAGS = -lvamp-hostsdk -lsndfile EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj" diff --git a/vamphost/src/main.cpp b/vamphost/src/main.cpp index 1ef19ab..6a8d8f1 100644 --- a/vamphost/src/main.cpp +++ b/vamphost/src/main.cpp @@ -7,7 +7,7 @@ int main( ){ ofAppGlutWindow window; - ofSetupOpenGL(&window, 1024,768, OF_FULLSCREEN); // <-------- setup the GL context + ofSetupOpenGL(&window, 1024,768, OF_WINDOW); // <-------- setup the GL context // this kicks off the running of my app // can be OF_WINDOW or OF_FULLSCREEN diff --git a/vamphost/src/ofxVamphost.cpp b/vamphost/src/ofxVamphost.cpp index 3da842b..fc8bbf0 100644 --- a/vamphost/src/ofxVamphost.cpp +++ b/vamphost/src/ofxVamphost.cpp @@ -2,22 +2,18 @@ using namespace std; -bool Vamphost::init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,const int &_outputNo,const string &_output){ +int Vamphost::getRT(){ + return rt.msec(); +} + +int Vamphost::init(const string &soname,const string &id,const int &_channels,const int &_rate,const int &_outputNo,const string &_output){ //stuff that only happens once channels =_channels; - samples=_samples; rate=_rate; - bits=_bits; outputNo=_outputNo; output=_output; - //http://www.mega-nerd.com/libsndfile/api.html#note1 - //libsndfile returns -1..1 for fp data - bytes=(bits>>3); - stride=channels*bytes; - scale=(1.0f/pow(2.0f,bits)); - features[0.0f]=0; loader = PluginLoader::getInstance(); @@ -26,7 +22,7 @@ bool Vamphost::init(const string &soname,const string &id,const int &_channels,c if (!plugin) { cerr << ": ERROR: Failed to load plugin \"" << id << "\" from library \"" << soname << "\"" << endl; - return false; + return -1; } cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl; @@ -84,7 +80,7 @@ bool Vamphost::init(const string &soname,const string &id,const int &_channels,c if (outputs.empty()) { cerr << "ERROR: Plugin has no outputs!" << endl; - return false; + return -1; } if (outputNo < 0) { @@ -96,13 +92,13 @@ bool Vamphost::init(const string &soname,const string &id,const int &_channels,c } if (outputNo < 0) { cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl; - return false; + return -1; } } else { if (int(outputs.size()) <= outputNo) { cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; - return false; + return -1; } } od = outputs[outputNo]; @@ -112,7 +108,7 @@ bool Vamphost::init(const string &soname,const string &id,const int &_channels,c cerr << "ERROR: Plugin initialise (channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << ") failed." << endl; - return false; + return -1; } wrapper = dynamic_cast<PluginWrapper *>(plugin); @@ -131,21 +127,24 @@ bool Vamphost::init(const string &soname,const string &id,const int &_channels,c featureNo=1; - return true; + return blockSize; } -void Vamphost::process_frame(unsigned char *data,int samples_in_frame){ +void Vamphost::process_frame(float *data,int samples_in_frame){ + // + // + + //plugbuf[0]=data; + // + // + int sample=0; //process the whole frame which may be f>1<f blocks //when the frame is finished leave the partial block for the next frame while(sample<samples_in_frame) { while(sample<samples_in_frame&&in_block<blockSize) { - for (int i=0;i<channels;i++) { - unsigned int this_val=0; - for (int j=0;j<bytes;j++) { - this_val+=data[(sample*stride)+(i*bytes)+j]<<(j*8); - } - plugbuf[i][in_block]=((float)((short)this_val))*scale; + for (int i=0;i<channels;i++) {} + plugbuf[i][in_block]=data[0]; //sample]; } in_block++; sample++; @@ -175,7 +174,7 @@ void Vamphost::process_frame(unsigned char *data,int samples_in_frame){ currentStep++; } } -} + void Vamphost::cleanup(){ //process final block diff --git a/vamphost/src/ofxVamphost.h b/vamphost/src/ofxVamphost.h index 2eb6a83..fe36d06 100644 --- a/vamphost/src/ofxVamphost.h +++ b/vamphost/src/ofxVamphost.h @@ -7,6 +7,7 @@ #include <map> #include <math.h> +#include <sndfile.h> using Vamp::Plugin; using Vamp::PluginHostAdapter; @@ -20,13 +21,14 @@ using Vamp::HostExt::PluginInputDomainAdapter; class Vamphost{ //can load any vamp analysis plugin and present its data with a unified interface public: - bool init(const std::string &soname,const std::string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,const int &_outputNo=0,const std::string &_output=""); - void process_frame(unsigned char *data,int samples_in_frame); + int init(const std::string &soname,const std::string &id,const int &_channels,const int &_rate,const int &_outputNo=0,const std::string &_output=""); + void process_frame(float *data,int samples_in_frame); void cleanup(); std::map<float,int> features; //map<time,featureNo> //this is the best way to store features: because map allows to search for the key below and above the present time + int getRT(); private: PluginLoader *loader; diff --git a/vamphost/src/testApp.cpp b/vamphost/src/testApp.cpp index adf7416..d04ce5c 100644 --- a/vamphost/src/testApp.cpp +++ b/vamphost/src/testApp.cpp @@ -3,37 +3,199 @@ //-------------------------------------------------------------- void testApp::setup() { + ofSetVerticalSync(true); + ofSetCircleResolution(80); + ofBackground(54, 54, 54); + + // 0 output channels, + // 2 input channels + // 44100 samples per second + // 256 samples per buffer + // 4 num buffers (latency) + + soundStream.listDevices(); + + //if you want to set a different device id + //soundStream.setDeviceID(0); //bear in mind the device id corresponds to all audio devices, including input-only and output-only devices. + + int rate =44100; + int channels=2; + int outputNo=0; + + string soname="qm-vamp-plugins"; + string id="qm-tempotracker"; + int bufferSize = vamphost.init(soname,id,channels,rate,outputNo); + + + left.assign(bufferSize, 0.0); + right.assign(bufferSize, 0.0); + volHistory.assign(400, 0.0); + + bufferCounter = 0; + drawCounter = 0; + smoothedVol = 0.0; + scaledVol = 0.0; + + //if you want to set a different device id + //soundStream.setDeviceID(0); //bear in mind the device id corresponds to all audio devices, including input-only and output-only devices. + + soundStream.setup(this, 0, channels, rate, bufferSize, 4); + + + } //-------------------------------------------------------------- void testApp::update(){ + //lets scale the vol up to a 0-1 range + scaledVol = ofMap(smoothedVol, 0.0, 0.17, 0.0, 1.0, true); + + //lets record the volume into an array + volHistory.push_back( scaledVol ); + //if we are bigger the the size we want to record - lets drop the oldest value + if( volHistory.size() >= 400 ){ + volHistory.erase(volHistory.begin(), volHistory.begin()+1); + } } //-------------------------------------------------------------- void testApp::draw(){ - ofBackground(0, 0, 0); - ofSetColor(255, 255, 255); +ofSetColor(225); + ofDrawBitmapString("AUDIO INPUT EXAMPLE", 32, 32); + ofDrawBitmapString("press 's' to unpause the audio\n'e' to pause the audio", 31, 92); + + ofNoFill(); + + // draw the left channel: + ofPushStyle(); + ofPushMatrix(); + ofTranslate(32, 170, 0); + + ofSetColor(225); + ofDrawBitmapString("Left Channel", 4, 18); + + ofSetLineWidth(1); + ofRect(0, 0, 512, 200); + + ofSetColor(245, 58, 135); + ofSetLineWidth(3); + + ofBeginShape(); + for (int i = 0; i < left.size(); i++){ + ofVertex(i*2, 100 -left[i]*180.0f); + } + ofEndShape(false); + + ofPopMatrix(); + ofPopStyle(); + + // draw the right channel: + ofPushStyle(); + ofPushMatrix(); + ofTranslate(32, 370, 0); + + ofSetColor(225); + ofDrawBitmapString("Right Channel", 4, 18); + + ofSetLineWidth(1); + ofRect(0, 0, 512, 200); + + ofSetColor(245, 58, 135); + ofSetLineWidth(3); + + ofBeginShape(); + for (int i = 0; i < right.size(); i++){ + ofVertex(i*2, 100 -right[i]*180.0f); + } + ofEndShape(false); + + ofPopMatrix(); + ofPopStyle(); + + // draw the average volume: + ofPushStyle(); + ofPushMatrix(); + ofTranslate(565, 170, 0); + + ofSetColor(225); + ofDrawBitmapString("Scaled average vol (0-100): " + ofToString(scaledVol * 100.0, 0), 4, 18); + ofRect(0, 0, 400, 400); + + ofSetColor(245, 58, 135); + ofFill(); + ofCircle(200, 200, scaledVol * 190.0f); + + //lets draw the volume history as a graph + ofBeginShape(); + for (int i = 0; i < volHistory.size(); i++){ + if( i == 0 ) ofVertex(i, 400); + + ofVertex(i, 400 - volHistory[i] * 70); + + if( i == volHistory.size() -1 ) ofVertex(i, 400); + } + ofEndShape(false); + + ofPopMatrix(); + ofPopStyle(); + + drawCounter++; + + ofSetColor(225); + string reportString = "buffers received: "+ofToString(bufferCounter)+"\ndraw routines called: "+ofToString(drawCounter)+"\nticks: " + ofToString(soundStream.getTickCount()); + ofDrawBitmapString(reportString, 32, 589); + +} + +void testApp::audioIn(float * input, int bufferSize, int nChannels){ + + float curVol = 0.0; + + // samples are "interleaved" + int numCounted = 0; + + //lets go through each sample and calculate the root mean square which is a rough way to calculate volume + for (int i = 0; i < bufferSize; i++){ + left[i] = input[i*2]*0.5; + right[i] = input[i*2+1]*0.5; + + curVol += left[i] * left[i]; + curVol += right[i] * right[i]; + numCounted+=2; + } + + //this is how we get the mean of rms :) + curVol /= (float)numCounted; + + // this is how we get the root of rms :) + curVol = sqrt( curVol ); + + smoothedVol *= 0.93; + smoothedVol += 0.07 * curVol; + + bufferCounter++; + + vamphost.process_frame(input,bufferSize); } //-------------------------------------------------------------- void testApp::exit(){ - + vamphost.cleanup(); } //-------------------------------------------------------------- void testApp::keyPressed(int key){ - switch (key) { - case 's': - case 'S': - break; - case 'p': - case 'P': - break; + if( key == 's' ){ + soundStream.start(); + } + + if( key == 'e' ){ + soundStream.stop(); } } diff --git a/vamphost/src/testApp.h b/vamphost/src/testApp.h index 855889c..ad24233 100644 --- a/vamphost/src/testApp.h +++ b/vamphost/src/testApp.h @@ -20,8 +20,21 @@ public: void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); - + void audioIn(float * input, int bufferSize, int nChannels); + + vector <float> left; + vector <float> right; + vector <float> volHistory; + + int bufferCounter; + int drawCounter; + + float smoothedVol; + float scaledVol; + + ofSoundStream soundStream; + Vamphost vamphost; }; |
