# HG changeset patch # User Chris Cannam # Date 1327589205 0 # Node ID 93dfb83c6f828736cfbc9d5ceaa9006d59afaa63 # Parent 3dd55efc53ca7a74a99e3e7cd2d431f1fabe5c76 Complete implementation of getOutputDescriptors diff -r 3dd55efc53ca -r 93dfb83c6f82 Makefile --- 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) diff -r 3dd55efc53ca -r 93dfb83c6f82 org/vamp_plugins/test.java --- 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"); } diff -r 3dd55efc53ca -r 93dfb83c6f82 src/Plugin.cpp --- 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 #include "handle.h" +#include "getset.h" + +#include using Vamp::Plugin; using Vamp::PluginBase; @@ -131,20 +134,14 @@ Plugin *p = getHandle(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, "", "(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, "", "()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 diff -r 3dd55efc53ca -r 93dfb83c6f82 src/getset.cpp --- /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 + +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 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; +} + diff -r 3dd55efc53ca -r 93dfb83c6f82 src/getset.h --- /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 + +#include +#include + +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 value); + +extern jmethodID +getEnumValueOfMethod(JNIEnv *env); + +#endif