changeset 7:93dfb83c6f82

Complete implementation of getOutputDescriptors
author Chris Cannam
date Thu, 26 Jan 2012 14:46:45 +0000
parents 3dd55efc53ca
children f3fc15d737eb
files Makefile org/vamp_plugins/test.java src/Plugin.cpp src/getset.cpp src/getset.h
diffstat 5 files changed, 177 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Jan 25 15:30:12 2012 +0000
+++ b/Makefile	Thu Jan 26 14:46:45 2012 +0000
@@ -1,8 +1,11 @@
 
 LIBRARY := libvamp-jni.so
-OBJFILES := src/PluginLoader.o src/Plugin.o
+OBJFILES := src/PluginLoader.o src/Plugin.o src/getset.o
 INCLUDES := -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
-CXXFLAGS := $(INCLUDES)
+CXXFLAGS := $(INCLUDES) -g
 
 $(LIBRARY): $(OBJFILES)
 	$(CXX) -shared -o $@ $^ -lvamp-hostsdk
+
+clean:
+	rm -f $(OBJFILES)
--- a/org/vamp_plugins/test.java	Wed Jan 25 15:30:12 2012 +0000
+++ b/org/vamp_plugins/test.java	Thu Jan 26 14:46:45 2012 +0000
@@ -7,7 +7,7 @@
 	
 	// This is a plugin we know we have installed
 //	String key = "vamp-example-plugins:percussiononsets";
-	String key = "qm-vamp-plugins:qm-onsets";
+	String key = "qm-vamp-plugins:qm-onsetdetector";
 
 	PluginLoader loader = PluginLoader.getInstance();
 	
@@ -28,6 +28,11 @@
 	    for (int i = 0; i < progs.length; ++i) {
 		System.out.println(i + ": " + progs[i]);
 	    }
+	    OutputDescriptor[] outputs = p.getOutputDescriptors();
+	    System.out.println("Plugin has " + outputs.length + " output(s)");
+	    for (int i = 0; i < outputs.length; ++i) {
+		System.out.println(i + ": " + outputs[i].identifier + " (sample type: " + outputs[i].sampleType + ")");
+	    }
 	} catch (PluginLoader.LoadFailedException e) {
 	    System.out.println("Plugin load failed");
 	}
--- a/src/Plugin.cpp	Wed Jan 25 15:30:12 2012 +0000
+++ b/src/Plugin.cpp	Thu Jan 26 14:46:45 2012 +0000
@@ -3,6 +3,9 @@
 #include <vamp-hostsdk/Plugin.h>
 
 #include "handle.h"
+#include "getset.h"
+
+#include <iostream>
 
 using Vamp::Plugin;
 using Vamp::PluginBase;
@@ -131,20 +134,14 @@
     Plugin *p = getHandle<Plugin>(env, obj);
     Plugin::InputDomain d = p->getInputDomain();
 
-    jclass enumClass = env->FindClass("java/lang/Enum");
     jclass ourEnumClass = env->FindClass("org/vamp_plugins/Plugin$InputDomain");
 
-    // Enum.valueOf(Class, String) returns Enum
-    jmethodID valueOfMethod = env->GetStaticMethodID
-	(enumClass, "valueOf",
-	 "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
-
     std::string dname = "TimeDomain";
     if (d == Plugin::FrequencyDomain) dname = "FrequencyDomain";
 
     return env->CallStaticObjectMethod
-	(ourEnumClass, valueOfMethod, ourEnumClass,
-	 env->NewStringUTF(dname.c_str()));
+	(ourEnumClass, getEnumValueOfMethod(env), ourEnumClass,
+	 env->NewStringUTF(dname.c_str())); //!!! string leaked!
 }
 
 jint
@@ -183,16 +180,66 @@
     jclass descClass = env->FindClass("org/vamp_plugins/OutputDescriptor");
     jobjectArray result = env->NewObjectArray(outputs.size(), descClass, 0);
     for (int i = 0; i < outputs.size(); ++i) {
-	jmethodID ctor = env->GetMethodID(descClass, "<init>", "(V)V");
-	jobject descriptor = env->NewObject(descClass, ctor);
-	env->SetObjectField(descriptor, env->GetFieldID(descClass, "identifier", "Ljava/lang/String;"), env->NewStringUTF(outputs[i].identifier.c_str()));
 
-	//!!!
+	std::cerr << " *** " << i << std::endl;
 
+	jmethodID ctor = env->GetMethodID(descClass, "<init>", "()V");
 
-	env->SetObjectArrayElement(result, i, descriptor);
+	std::cerr << " ctor method: " << ctor << std::endl;
+
+	jobject desc = env->NewObject(descClass, ctor);
+
+	std::cerr << " new object created " << std::endl;
+
+	setStringField(env, desc, "identifier", outputs[i].identifier);
+	setStringField(env, desc, "name", outputs[i].name);
+	setStringField(env, desc, "description", outputs[i].description);
+	setStringField(env, desc, "unit", outputs[i].unit);
+	setBooleanField(env, desc, "hasFixedBinCount", outputs[i].hasFixedBinCount);
+	setIntField(env, desc, "binCount", outputs[i].binCount);
+	setStringArrayField(env, desc, "binNames", outputs[i].binNames);
+	setBooleanField(env, desc, "hasKnownExtents", outputs[i].hasKnownExtents);
+	setFloatField(env, desc, "minValue", outputs[i].minValue);
+	setFloatField(env, desc, "maxValue", outputs[i].maxValue);
+	setBooleanField(env, desc, "isQuantized", outputs[i].isQuantized);
+	setFloatField(env, desc, "quantizeStep", outputs[i].quantizeStep);
+	setFloatField(env, desc, "sampleRate", outputs[i].sampleRate);
+	setBooleanField(env, desc, "hasDuration", outputs[i].hasDuration);
+
+	jclass sampleTypeClass = env->FindClass
+	    ("org/vamp_plugins/OutputDescriptor$SampleType");
+
+	const char *stype;
+	switch (outputs[i].sampleType) {
+	case Plugin::OutputDescriptor::OneSamplePerStep:
+	    stype = "OneSamplePerStep";
+	    break;
+	case Plugin::OutputDescriptor::FixedSampleRate:
+	    stype = "FixedSampleRate";
+	    break;
+	case Plugin::OutputDescriptor::VariableSampleRate:
+	    stype = "VariableSampleRate";
+	    break;
+	}
+
+	std::cerr << "stype = " << stype << ", sample type class = " << sampleTypeClass << std::endl;
+
+	jobject sampleType = env->CallStaticObjectMethod
+    	    (sampleTypeClass, getEnumValueOfMethod(env),
+	     sampleTypeClass, env->NewStringUTF(stype));//!!! string leaked!
+
+	std::cerr << "sampleType = " << sampleType << std::endl;
+
+	setObjectField(env, desc, "sampleType",
+		       "Lorg/vamp_plugins/OutputDescriptor$SampleType;",
+		       sampleType);
+
+	std::cerr << "set enum OK" << std::endl;
+
+	env->SetObjectArrayElement(result, i, desc);
     }
-    return 0;
+
+    return result;
 }
 
 jobject
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/getset.cpp	Thu Jan 26 14:46:45 2012 +0000
@@ -0,0 +1,74 @@
+
+#include "getset.h"
+
+#include <iostream>
+
+void
+setStringField(JNIEnv *env, jobject obj, std::string name, std::string value)
+{
+    jclass cls = env->GetObjectClass(obj);
+    env->SetObjectField(obj,
+			env->GetFieldID(cls, name.c_str(), "Ljava/lang/String;"),
+			env->NewStringUTF(value.c_str()));
+}
+
+void
+setFloatField(JNIEnv *env, jobject obj, std::string name, float value)
+{
+    jclass cls = env->GetObjectClass(obj);
+    env->SetFloatField(obj,
+		       env->GetFieldID(cls, name.c_str(), "F"),
+		       value);
+}
+
+void
+setBooleanField(JNIEnv *env, jobject obj, std::string name, bool value)
+{
+    jclass cls = env->GetObjectClass(obj);
+    env->SetBooleanField(obj,
+			 env->GetFieldID(cls, name.c_str(), "Z"),
+			 value);
+}
+
+void
+setIntField(JNIEnv *env, jobject obj, std::string name, int value)
+{
+    jclass cls = env->GetObjectClass(obj);
+    env->SetIntField(obj,
+		     env->GetFieldID(cls, name.c_str(), "I"),
+		     value);
+}
+
+void
+setObjectField(JNIEnv *env, jobject obj, std::string name, std::string type, jobject value)
+{
+    jclass cls = env->GetObjectClass(obj);
+    jfieldID field = env->GetFieldID(cls, name.c_str(), type.c_str());
+    std::cerr << "setObjectField: class = " << cls << ", object = " << obj << ", field = " << field << ", value = " << value << std::endl;
+    env->SetObjectField(obj, field, value);
+}
+
+void
+setStringArrayField(JNIEnv *env, jobject obj, std::string name, std::vector<std::string> values)
+{
+    jclass strCls = env->FindClass("java/lang/String");
+    jobjectArray jarr = env->NewObjectArray(values.size(), strCls, 0);
+    for (int i = 0; i < values.size(); ++i) {
+	env->SetObjectArrayElement(jarr, i, env->NewStringUTF(values[i].c_str()));
+    }
+    setObjectField(env, obj, name, "[Ljava/lang/String;", jarr);
+}
+
+jmethodID
+getEnumValueOfMethod(JNIEnv *env)
+{
+    jclass enumClass = env->FindClass("java/lang/Enum");
+
+    // Enum.valueOf(Class, String) returns Enum
+    jmethodID valueOfMethod = env->GetStaticMethodID
+	(enumClass, "valueOf",
+	 "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
+
+    return valueOfMethod;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/getset.h	Thu Jan 26 14:46:45 2012 +0000
@@ -0,0 +1,31 @@
+
+#ifndef _GETSET_H_INCLUDED_
+#define _GETSET_H_INCLUDED_
+
+#include <jni.h>
+
+#include <string>
+#include <vector>
+
+extern void
+setStringField(JNIEnv *env, jobject obj, std::string name, std::string value);
+
+extern void
+setFloatField(JNIEnv *env, jobject obj, std::string name, float value);
+
+extern void
+setBooleanField(JNIEnv *env, jobject obj, std::string name, bool value);
+
+extern void
+setIntField(JNIEnv *env, jobject obj, std::string name, int value);
+
+extern void
+setObjectField(JNIEnv *env, jobject obj, std::string name, std::string type, jobject value);
+
+extern void
+setStringArrayField(JNIEnv *env, jobject obj, std::string name, std::vector<std::string> value);
+
+extern jmethodID
+getEnumValueOfMethod(JNIEnv *env);
+
+#endif