summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xvamphost/config.make4
-rw-r--r--vamphost/src/main.cpp2
-rw-r--r--vamphost/src/ofxVamphost.cpp45
-rw-r--r--vamphost/src/ofxVamphost.h6
-rw-r--r--vamphost/src/testApp.cpp182
-rw-r--r--vamphost/src/testApp.h15
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;
};