comparison bindings/java/ext/libAudioDB_JNI.c @ 726:fe2282b9bfb0

Initial querying: doesn't return results yet, but handles almost all params.
author mas01mj
date Mon, 26 Jul 2010 13:19:09 +0000
parents 7e1fa27b67ee
children 4d9e4ff0a9cd
comparison
equal deleted inserted replaced
725:7e1fa27b67ee 726:fe2282b9bfb0
3 #include "org_omras2_AudioDB_Mode.h" 3 #include "org_omras2_AudioDB_Mode.h"
4 #include <jni.h> 4 #include <jni.h>
5 #include "audioDB_API.h" 5 #include "audioDB_API.h"
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <string.h>
8 9
9 // Following Ben's lead here! 10 // Following Ben's lead here!
10 #define ADB_HEADER_FLAG_L2NORM 0x1 11 #define ADB_HEADER_FLAG_L2NORM 0x1
11 #define ADB_HEADER_FLAG_POWER 0x4 12 #define ADB_HEADER_FLAG_POWER 0x4
12 #define ADB_HEADER_FLAG_TIMES 0x20 13 #define ADB_HEADER_FLAG_TIMES 0x20
13 #define ADB_HEADER_FLAG_REFERENCES 0x40 14 #define ADB_HEADER_FLAG_REFERENCES 0x40
14 15
16 double get_int_val(JNIEnv *env, jclass classValue, jobject objectValue, char* field, int defaultValue)
17 {
18 jfieldID fid = (*env)->GetFieldID(env, classValue, field, "I");
19 if(fid == NULL) return defaultValue;
20 int val = (*env)->GetIntField(env, objectValue, fid);
21 return (val ? val : defaultValue);
22 }
23
24 double get_double_val(JNIEnv *env, jclass classValue, jobject objectValue, char* field, double defaultValue)
25 {
26 jfieldID fid = (*env)->GetFieldID(env, classValue, field, "D");
27 if(fid == NULL) return defaultValue;
28 double val = (*env)->GetDoubleField(env, objectValue, fid);
29 return (val ? val : defaultValue);
30 }
31
32 const char* get_enum_val(JNIEnv *env, jclass queryClass, jobject queryObject, char* fieldName, char* enumClassName)
33 {
34 char signature[strlen(enumClassName)+2];
35 sprintf(signature, "L%s;", enumClassName);
36
37 // Get the value of the enum field
38 jfieldID fid = (*env)->GetFieldID(env, queryClass, fieldName, signature);
39 if(fid == NULL) return;
40
41 jobject field = (*env)->GetObjectField(env, queryObject, fid);
42 if(field == NULL) return;
43
44 // Retrieve the string value via name()
45 jclass enumClass = (*env)->FindClass(env, enumClassName);
46 if(enumClass == NULL) return;
47
48 jmethodID getNameMethod = (*env)->GetMethodID(env, enumClass, "name", "()Ljava/lang/String;");
49 if(getNameMethod == NULL) return;
50
51 jstring value = (jstring)((*env)->CallObjectMethod(env, field, getNameMethod));
52 if(value == NULL) return;
53
54 return (*env)->GetStringUTFChars(env, value, 0);
55 }
15 56
16 adb_t* get_handle(JNIEnv *env, jobject obj) 57 adb_t* get_handle(JNIEnv *env, jobject obj)
17 { 58 {
18 // Fetch the adb pointer 59 // Fetch the adb pointer
19 60
49 90
50 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1open (JNIEnv *env, jobject obj, jstring path, jobject mode) 91 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1open (JNIEnv *env, jobject obj, jstring path, jobject mode)
51 { 92 {
52 // TODO: If we have a handle, close the old one. 93 // TODO: If we have a handle, close the old one.
53 if(get_handle(env, obj)) 94 if(get_handle(env, obj))
54 { 95 return;
55 return;
56 }
57 96
58 jclass modeClass = (*env)->FindClass(env, "org/omras2/AudioDB$Mode"); 97 jclass modeClass = (*env)->FindClass(env, "org/omras2/AudioDB$Mode");
59 jmethodID getNameMethod = (*env)->GetMethodID(env, modeClass, "name", "()Ljava/lang/String;"); 98 jmethodID getNameMethod = (*env)->GetMethodID(env, modeClass, "name", "()Ljava/lang/String;");
60 jstring value = (jstring)(*env)->CallObjectMethod(env, mode, getNameMethod); 99 jstring value = (jstring)(*env)->CallObjectMethod(env, mode, getNameMethod);
61 const char* openMode = (*env)->GetStringUTFChars(env, value, 0); 100 const char* openMode = (*env)->GetStringUTFChars(env, value, 0);
203 (*env)->DeleteLocalRef(env, statusClass); 242 (*env)->DeleteLocalRef(env, statusClass);
204 243
205 return result; 244 return result;
206 } 245 }
207 246
247 JNIEXPORT void JNICALL Java_org_omras2_AudioDB_audiodb_1query_1by_1key(JNIEnv *env, jobject adbobj, jstring key, jobject queryObject)
248 {
249 adb_t* handle = get_handle(env, adbobj);
250
251 if(!handle)
252 return;
253
254 const char* keyStr = (*env)->GetStringUTFChars(env, key, NULL);
255 if (keyStr == NULL)
256 return;
257
258 adb_query_spec_t* spec = (adb_query_spec_t *)malloc(sizeof(adb_query_spec_t));
259 spec->qid.datum = (adb_datum_t *)malloc(sizeof(adb_datum_t));
260 adb_query_results_t* result = (adb_query_results_t *)malloc(sizeof(adb_query_results_t));
261
262 // As in python bindings
263 spec->refine.flags = 0;
264
265 jclass queryClass = (*env)->GetObjectClass(env, queryObject);
266
267 spec->qid.sequence_length = get_int_val(env, queryClass, queryObject, "seqLength", 16);
268 spec->qid.sequence_start = get_int_val(env, queryClass, queryObject, "seqStart", 0);
269 spec->params.npoints = get_int_val(env, queryClass, queryObject, "npoints", 1);
270 spec->params.ntracks = get_int_val(env, queryClass, queryObject, "ntracks", 100);
271
272 jfieldID fid = (*env)->GetFieldID(env, queryClass, "exhaustive", "Z");
273 if(fid == NULL) return;
274 if((*env)->GetBooleanField(env, queryObject, fid)) {
275 spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_EXHAUSTIVE;
276 }
277
278 fid = (*env)->GetFieldID(env, queryClass, "hasFalsePositives", "Z");
279 if(fid == NULL) return;
280 if((*env)->GetBooleanField(env, queryObject, fid)) {
281 spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_ALLOW_FALSE_POSITIVES;
282 }
283
284 const char* accType = get_enum_val(env, queryClass, queryObject, "accumulation", "org/omras2/Query$Accumulation");
285 const char* distType = get_enum_val(env, queryClass, queryObject, "distance", "org/omras2/Query$Distance");
286
287 if(strcmp(accType, "DB") == 0)
288 spec->params.accumulation = ADB_ACCUMULATION_DB;
289 else if(strcmp(accType, "PER_TRACK") == 0)
290 spec->params.accumulation = ADB_ACCUMULATION_PER_TRACK;
291 else if(strcmp(accType, "ONE_TO_ONE") == 0)
292 spec->params.accumulation = ADB_ACCUMULATION_ONE_TO_ONE;
293 else {
294 printf("Invalid acc\n");
295 return;
296 }
297
298 if(strcmp(distType, "DOT_PRODUCT") == 0)
299 spec->params.distance = ADB_DISTANCE_DOT_PRODUCT;
300 else if(strcmp(distType, "EUCLIDEAN_NORMED") == 0)
301 spec->params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED;
302 else if(strcmp(distType, "EUCLIDEAN") == 0)
303 spec->params.distance = ADB_DISTANCE_EUCLIDEAN;
304 else {
305 printf("Invalid dist\n");
306 return;
307 }
308
309 // Rest of refine
310
311 double radius = get_double_val(env, queryClass, queryObject, "radius", 0);
312 double absThres = get_double_val(env, queryClass, queryObject, "absThres", 0);
313 double relThres = get_double_val(env, queryClass, queryObject, "relThres", 0);
314 double durRatio = get_double_val(env, queryClass, queryObject, "durRatio", 0);
315 int hopSize = get_int_val(env, queryClass, queryObject, "hopSize", 0);
316
317 if(radius) {
318 spec->refine.flags |= ADB_REFINE_RADIUS;
319 spec->refine.radius = radius;
320 }
321
322 if(absThres) {
323 spec->refine.flags |= ADB_REFINE_ABSOLUTE_THRESHOLD;
324 spec->refine.absolute_threshold = absThres;
325 }
326
327 if(relThres) {
328 spec->refine.flags |= ADB_REFINE_RELATIVE_THRESHOLD;
329 spec->refine.relative_threshold = relThres;
330 }
331
332 if(durRatio) {
333 spec->refine.flags |= ADB_REFINE_DURATION_RATIO;
334 spec->refine.duration_ratio = durRatio;
335 }
336
337 if(hopSize) {
338 spec->refine.flags |= ADB_REFINE_HOP_SIZE;
339 spec->refine.qhopsize = hopSize;
340 spec->refine.ihopsize = hopSize;
341 }
342
343 spec->qid.datum->data = NULL;
344 spec->qid.datum->power = NULL;
345 spec->qid.datum->times = NULL;
346
347 printf("seq length: %d seq start: %d points: %d tracks: %d\n",
348 spec->qid.sequence_length,
349 spec->qid.sequence_start,
350 spec->params.npoints,
351 spec->params.ntracks);
352 printf("Radius: %f Abs: %f Rel: %f Dur: %f Hop: %d\n", radius, absThres, relThres, durRatio, hopSize);
353 printf("Key: %s Acc: %s Dist: %s\n", keyStr, accType, distType);
354
355 int ok = audiodb_retrieve_datum(handle, keyStr, spec->qid.datum);
356 if(ok != 0) {
357 printf("No datum\n");
358 return;
359 }
360 result = audiodb_query_spec(handle, spec);
361
362 if(result == NULL) {
363 printf("No result\n");
364 return;
365 }
366 printf("OK: %d\n", ok);
367 (*env)->DeleteLocalRef(env, queryClass);
368 }
369