summaryrefslogtreecommitdiff
path: root/vamphost
diff options
context:
space:
mode:
Diffstat (limited to 'vamphost')
-rwxr-xr-xvamphost/Makefile2
-rw-r--r--vamphost/addons.make1
-rwxr-xr-xvamphost/config.make57
-rw-r--r--vamphost/src/main.cpp17
-rw-r--r--vamphost/src/ofxVamphost.cpp212
-rw-r--r--vamphost/src/ofxVamphost.h49
-rw-r--r--vamphost/src/testApp.cpp69
-rw-r--r--vamphost/src/testApp.h28
8 files changed, 435 insertions, 0 deletions
diff --git a/vamphost/Makefile b/vamphost/Makefile
new file mode 100755
index 0000000..2d83a77
--- /dev/null
+++ b/vamphost/Makefile
@@ -0,0 +1,2 @@
+include config.make
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/Makefile.examples
diff --git a/vamphost/addons.make b/vamphost/addons.make
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/vamphost/addons.make
@@ -0,0 +1 @@
+
diff --git a/vamphost/config.make b/vamphost/config.make
new file mode 100755
index 0000000..a4db95a
--- /dev/null
+++ b/vamphost/config.make
@@ -0,0 +1,57 @@
+# add custom variables to this file
+
+# OF_ROOT allows to move projects outside apps/* just set this variable to the
+# absoulte path to the OF root folder
+
+#OF_ROOT = ../../openFrameworks
+OF_ROOT = /home/tim/workspace/openFrameworks
+
+
+# USER_CFLAGS allows to pass custom flags to the compiler
+# 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_LDFLAGS allows to pass custom flags to the linker
+# for example libraries like:
+# USER_LDFLAGS = libs/libawesomelib.a
+
+USER_LDFLAGS = -lvamp-hostsdk
+
+
+EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj"
+
+# change this to add different compiler optimizations to your project
+
+USER_COMPILER_OPTIMIZATION = -march=native -mtune=native -Os
+
+
+# android specific, in case you want to use different optimizations
+USER_LIBS_ARM =
+USER_LIBS_ARM7 =
+USER_LIBS_NEON =
+
+# android optimizations
+
+ANDROID_COMPILER_OPTIMIZATION = -Os
+
+NDK_PLATFORM = android-8
+
+# uncomment this for custom application name (if the folder name is different than the application name)
+#APPNAME = folderName
+
+# uncomment this for custom package name, must be the same as the java package that contains OFActivity
+#PKGNAME = cc.openframeworks.$(APPNAME)
+
+
+
+
+
+# linux arm flags
+
+LINUX_ARM7_COMPILER_OPTIMIZATIONS = -march=armv7-a -mtune=cortex-a8 -finline-functions -funroll-all-loops -O3 -funsafe-math-optimizations -mfpu=neon -ftree-vectorize -mfloat-abi=hard -mfpu=vfp
+
+
+
diff --git a/vamphost/src/main.cpp b/vamphost/src/main.cpp
new file mode 100644
index 0000000..1ef19ab
--- /dev/null
+++ b/vamphost/src/main.cpp
@@ -0,0 +1,17 @@
+
+#include "testApp.h"
+#include "ofMain.h"
+#include "ofAppGlutWindow.h"
+
+//========================================================================
+int main( ){
+
+ ofAppGlutWindow window;
+ ofSetupOpenGL(&window, 1024,768, OF_FULLSCREEN); // <-------- setup the GL context
+
+ // this kicks off the running of my app
+ // can be OF_WINDOW or OF_FULLSCREEN
+ // pass in width and height too:
+ ofRunApp( new testApp());
+
+}
diff --git a/vamphost/src/ofxVamphost.cpp b/vamphost/src/ofxVamphost.cpp
new file mode 100644
index 0000000..3da842b
--- /dev/null
+++ b/vamphost/src/ofxVamphost.cpp
@@ -0,0 +1,212 @@
+#include "ofxVamphost.h"
+
+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){
+
+ //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();
+ key = loader->composePluginKey(soname, id);
+ plugin = loader->loadPlugin(key, _rate, PluginLoader::ADAPT_ALL_SAFE);
+ if (!plugin) {
+ cerr << ": ERROR: Failed to load plugin \"" << id
+ << "\" from library \"" << soname << "\"" << endl;
+ return false;
+ }
+
+ cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
+
+ blockSize = plugin->getPreferredBlockSize();
+ stepSize = plugin->getPreferredStepSize();
+
+ if (blockSize == 0) {
+ blockSize = 1024;
+ }
+ if (stepSize == 0) {
+ if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
+ stepSize = blockSize/2;
+ } else {
+ stepSize = blockSize;
+ }
+ }
+ else if (stepSize > blockSize) {
+ cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
+ if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
+ blockSize = stepSize * 2;
+ } else {
+ blockSize = stepSize;
+ }
+ cerr << blockSize << endl;
+ }
+ overlapSize = blockSize - stepSize;
+ currentStep = 0;
+ finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
+
+ plugbuf = new float*[channels];
+ for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
+
+ cerr << "Using block size = " << blockSize << ", step size = "
+ << stepSize << endl;
+
+ // The channel queries here are for informational purposes only --
+ // a PluginChannelAdapter is being used automatically behind the
+ // scenes, and it will take case of any channel mismatch
+
+ int minch = plugin->getMinChannelCount();
+ int maxch = plugin->getMaxChannelCount();
+ cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
+ cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
+
+ Plugin::OutputList outputs = plugin->getOutputDescriptors();
+ Plugin::OutputDescriptor od;
+
+ int returnValue = 1;
+ int prog = 0;
+
+ RealTime rt;
+ PluginWrapper *wrapper = 0;
+ RealTime adjustment = RealTime::zeroTime;
+
+ if (outputs.empty()) {
+ cerr << "ERROR: Plugin has no outputs!" << endl;
+ return false;
+ }
+
+ if (outputNo < 0) {
+ for (size_t oi = 0; oi < outputs.size(); ++oi) {
+ if (outputs[oi].identifier == output) {
+ outputNo = oi;
+ break;
+ }
+ }
+ if (outputNo < 0) {
+ cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
+ return false;
+ }
+ }
+ else {
+ if (int(outputs.size()) <= outputNo) {
+ cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
+ return false;
+ }
+ }
+ od = outputs[outputNo];
+ cerr << "Output is: \"" << od.identifier << "\"" << endl;
+
+ if (!plugin->initialise(channels, stepSize, blockSize)) {
+ cerr << "ERROR: Plugin initialise (channels = " << channels
+ << ", stepSize = " << stepSize << ", blockSize = "
+ << blockSize << ") failed." << endl;
+ return false;
+ }
+
+ wrapper = dynamic_cast<PluginWrapper *>(plugin);
+ if (wrapper) {
+ // See documentation for
+ // PluginInputDomainAdapter::getTimestampAdjustment
+ PluginInputDomainAdapter *ida =wrapper->getWrapper<PluginInputDomainAdapter>();
+ if (ida) adjustment = ida->getTimestampAdjustment();
+ }
+
+ //everything is prepared to start consuming data in blocks
+
+ in_block=0;
+ blocks_processed=0;
+ currentStep=0;
+
+ featureNo=1;
+
+ return true;
+}
+void Vamphost::process_frame(unsigned char *data,int samples_in_frame){
+ 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;
+ }
+ in_block++;
+ sample++;
+ }
+ if (in_block==blockSize) {
+ //block is ready to be processed
+ //cerr<<plugin->getIdentifier()<<" processed block "<<blocks_processed<<endl;
+
+ //I /think/ that the vamp plugin keeps processing through the plugbuf until it encounters 0s
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
+
+ Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
+
+ for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
+ features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
+ featureNo++;
+ }
+
+ //shunt it down
+ for (int i=0;i<blockSize-stepSize;i++){
+ for (int j=0;j<channels;j++){
+ plugbuf[j][i]=plugbuf[j][i+stepSize];
+ }
+ }
+
+ in_block-=stepSize;
+ currentStep++;
+ }
+ }
+}
+void Vamphost::cleanup(){
+
+ //process final block
+ while(in_block<blockSize) {
+ for (int i=0;i<channels;i++) {
+ plugbuf[i][in_block]=0.0f;
+ }
+ in_block++;
+ }
+
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
+
+ Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
+
+ for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
+ features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
+ featureNo++;
+ }
+
+ feat=plugin->getRemainingFeatures();
+
+ for (unsigned int i = 0; i < feat[outputNo].size(); ++i) {
+ features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo;
+ featureNo++;
+ }
+
+ cerr<<plugin->getIdentifier()<<" found "<<(features.size()-1)<<" features"<<endl;
+ //deal with left over data?
+ for (int c = 0; c < channels; ++c) {
+ delete[] plugbuf[c];
+ }
+ delete[] plugbuf;
+ delete plugin;
+}
diff --git a/vamphost/src/ofxVamphost.h b/vamphost/src/ofxVamphost.h
new file mode 100644
index 0000000..2eb6a83
--- /dev/null
+++ b/vamphost/src/ofxVamphost.h
@@ -0,0 +1,49 @@
+#ifndef OFXVAMPHOST_H_
+#define OFXVAMPHOST_H_
+
+#include <vamp-hostsdk/PluginHostAdapter.h>
+#include <vamp-hostsdk/PluginInputDomainAdapter.h>
+#include <vamp-hostsdk/PluginLoader.h>
+
+#include <map>
+#include <math.h>
+
+using Vamp::Plugin;
+using Vamp::PluginHostAdapter;
+using Vamp::RealTime;
+using Vamp::HostExt::PluginLoader;
+using Vamp::HostExt::PluginWrapper;
+using Vamp::HostExt::PluginInputDomainAdapter;
+
+#define HOST_VERSION "1.5"
+
+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);
+ 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
+
+ private:
+ PluginLoader *loader;
+ PluginLoader::PluginKey key;
+ Plugin *plugin;
+ RealTime rt;
+ int channels,bits,samples,rate;
+ int bytes,stride;
+ float scale;
+ int blockSize,stepSize,overlapSize,finalStepsRemaining,currentStep,outputNo;
+ int in_block,blocks_processed;
+ std::string output;
+ float **plugbuf;
+
+ int featureNo;
+
+};
+
+#endif
+
diff --git a/vamphost/src/testApp.cpp b/vamphost/src/testApp.cpp
new file mode 100644
index 0000000..adf7416
--- /dev/null
+++ b/vamphost/src/testApp.cpp
@@ -0,0 +1,69 @@
+#include "testApp.h"
+
+//--------------------------------------------------------------
+void testApp::setup() {
+
+
+}
+
+
+//--------------------------------------------------------------
+void testApp::update(){
+
+}
+
+//--------------------------------------------------------------
+void testApp::draw(){
+ ofBackground(0, 0, 0);
+ ofSetColor(255, 255, 255);
+
+
+}
+
+//--------------------------------------------------------------
+void testApp::exit(){
+
+}
+
+//--------------------------------------------------------------
+void testApp::keyPressed(int key){
+ switch (key) {
+ case 's':
+ case 'S':
+ break;
+ case 'p':
+ case 'P':
+ break;
+ }
+}
+
+//--------------------------------------------------------------
+void testApp::keyReleased(int key){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseMoved(int x, int y ){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseDragged(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mousePressed(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::windowResized(int w, int h){
+
+}
+
diff --git a/vamphost/src/testApp.h b/vamphost/src/testApp.h
new file mode 100644
index 0000000..855889c
--- /dev/null
+++ b/vamphost/src/testApp.h
@@ -0,0 +1,28 @@
+#ifndef _TEST_APP
+#define _TEST_APP
+
+#include "ofMain.h"
+#include "ofxVamphost.h"
+
+
+class testApp : public ofBaseApp{
+
+public:
+ void setup();
+ void update();
+ void draw();
+ void exit();
+
+ void keyPressed (int key);
+ void keyReleased(int key);
+ void mouseMoved(int x, int y );
+ void mouseDragged(int x, int y, int button);
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void windowResized(int w, int h);
+
+
+
+};
+
+#endif