Mercurial > hg > audiodb
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 |