annotate bindings/java/ext/libAudioDB_JNI.c @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents a9978a6d0bb3
children
rev   line source
mas01mj@725 1 #include <sys/stat.h>
mas01mj@722 2 #include "org_omras2_AudioDB.h"
mas01mj@722 3 #include "org_omras2_AudioDB_Mode.h"
mas01mj@722 4 #include <jni.h>
mas01mj@722 5 #include "audioDB_API.h"
mas01mj@724 6 #include <stdlib.h>
mas01mj@725 7 #include <fcntl.h>
mas01mj@726 8 #include <string.h>
mas01mj@725 9
mas01mj@725 10 // Following Ben's lead here!
mas01mj@725 11 #define ADB_HEADER_FLAG_L2NORM 0x1
mas01mj@725 12 #define ADB_HEADER_FLAG_POWER 0x4
mas01mj@725 13 #define ADB_HEADER_FLAG_TIMES 0x20
mas01mj@725 14 #define ADB_HEADER_FLAG_REFERENCES 0x40
mas01mj@725 15
mas01mj@729 16 jdoubleArray get_double_array(JNIEnv *env, jclass classValue, jobject objectValue, char* field)
mas01mj@729 17 {
mas01mj@729 18 jfieldID fid = (*env)->GetFieldID(env, classValue, field, "[D");
mas01mj@729 19 if(fid == NULL) return NULL;
mas01mj@729 20 jdoubleArray arr = (*env)->GetObjectField(env, objectValue, fid);
mas01mj@729 21 return arr;
mas01mj@729 22 }
mas01mj@729 23
mas01mj@729 24 int get_int_val(JNIEnv *env, jclass classValue, jobject objectValue, char* field, int defaultValue)
mas01mj@726 25 {
mas01mj@726 26 jfieldID fid = (*env)->GetFieldID(env, classValue, field, "I");
mas01mj@726 27 if(fid == NULL) return defaultValue;
mas01mj@726 28 int val = (*env)->GetIntField(env, objectValue, fid);
mas01mj@726 29 return (val ? val : defaultValue);
mas01mj@726 30 }
mas01mj@726 31
mas01mj@726 32 double get_double_val(JNIEnv *env, jclass classValue, jobject objectValue, char* field, double defaultValue)
mas01mj@726 33 {
mas01mj@726 34 jfieldID fid = (*env)->GetFieldID(env, classValue, field, "D");
mas01mj@726 35 if(fid == NULL) return defaultValue;
mas01mj@726 36 double val = (*env)->GetDoubleField(env, objectValue, fid);
mas01mj@726 37 return (val ? val : defaultValue);
mas01mj@726 38 }
mas01mj@726 39
mas01mj@726 40 const char* get_enum_val(JNIEnv *env, jclass queryClass, jobject queryObject, char* fieldName, char* enumClassName)
mas01mj@726 41 {
mas01mj@726 42 char signature[strlen(enumClassName)+2];
mas01mj@726 43 sprintf(signature, "L%s;", enumClassName);
mas01mj@726 44
mas01mj@726 45 // Get the value of the enum field
mas01mj@726 46 jfieldID fid = (*env)->GetFieldID(env, queryClass, fieldName, signature);
mas01mj@726 47 if(fid == NULL) return;
mas01mj@726 48
mas01mj@726 49 jobject field = (*env)->GetObjectField(env, queryObject, fid);
mas01mj@726 50 if(field == NULL) return;
mas01mj@726 51
mas01mj@726 52 // Retrieve the string value via name()
mas01mj@726 53 jclass enumClass = (*env)->FindClass(env, enumClassName);
mas01mj@726 54 if(enumClass == NULL) return;
mas01mj@726 55
mas01mj@726 56 jmethodID getNameMethod = (*env)->GetMethodID(env, enumClass, "name", "()Ljava/lang/String;");
mas01mj@726 57 if(getNameMethod == NULL) return;
mas01mj@726 58
mas01mj@726 59 jstring value = (jstring)((*env)->CallObjectMethod(env, field, getNameMethod));
mas01mj@726 60 if(value == NULL) return;
mas01mj@726 61
mas01mj@726 62 return (*env)->GetStringUTFChars(env, value, 0);
mas01mj@726 63 }
mas01mj@725 64
mas01mj@725 65 adb_t* get_handle(JNIEnv *env, jobject obj)
mas01mj@725 66 {
mas01mj@725 67 // Fetch the adb pointer
mas01mj@725 68
mas01mj@725 69 adb_t *handle;
mas01mj@725 70
mas01mj@725 71 jclass adbClass = (*env)->GetObjectClass(env, obj);
mas01mj@725 72 jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J");
mas01mj@725 73 if(fid == NULL) {
mas01mj@725 74 return;
mas01mj@725 75 }
mas01mj@725 76
mas01mj@725 77 handle = (adb_t*)((*env)->GetLongField(env, obj, fid));
mas01mj@725 78 (*env)->DeleteLocalRef(env, adbClass);
mas01mj@725 79 return handle;
mas01mj@725 80 }
mas01mj@722 81
mas01mj@722 82 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1create (JNIEnv *env, jobject obj, jstring path, jint datasize, jint ntracks, jint datadim)
mas01mj@722 83 {
mas01mj@722 84 char buf[256];
mas01mj@722 85 const char *str;
mas01mj@722 86 str = (*env)->GetStringUTFChars(env, path, NULL);
mas01mj@722 87 if (str == NULL)
mas01mj@722 88 return;
mas01mj@722 89
mas01mj@722 90 adb_t *handle;
mas01mj@722 91 handle = audiodb_create(str, datasize, ntracks, datadim);
mas01mj@722 92 if(!handle)
mas01mj@722 93 return JNI_FALSE;
mas01mj@724 94
mas01mj@725 95 (*env)->ReleaseStringUTFChars(env, path, str);
mas01mj@725 96 return JNI_TRUE;
mas01mj@725 97 }
mas01mj@725 98
mas01mj@725 99 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1open (JNIEnv *env, jobject obj, jstring path, jobject mode)
mas01mj@725 100 {
mas01mj@725 101 // TODO: If we have a handle, close the old one.
mas01mj@725 102 if(get_handle(env, obj))
mas01mj@725 103 return;
mas01mj@725 104
mas01mj@725 105 jclass modeClass = (*env)->FindClass(env, "org/omras2/AudioDB$Mode");
mas01mj@725 106 jmethodID getNameMethod = (*env)->GetMethodID(env, modeClass, "name", "()Ljava/lang/String;");
mas01mj@725 107 jstring value = (jstring)(*env)->CallObjectMethod(env, mode, getNameMethod);
mas01mj@725 108 const char* openMode = (*env)->GetStringUTFChars(env, value, 0);
mas01mj@725 109 const char* pathVal = (*env)->GetStringUTFChars(env, path, 0);
mas01mj@725 110 int modeVal = 0;
mas01mj@725 111 if(strcmp(openMode, "O_RDWR") == 0)
mas01mj@725 112 {
mas01mj@725 113 modeVal = O_RDWR;
mas01mj@725 114 }
mas01mj@725 115 else if(strcmp(openMode, "O_RDONLY") == 0)
mas01mj@725 116 {
mas01mj@725 117 modeVal = O_RDONLY;
mas01mj@725 118 }
mas01mj@725 119 else
mas01mj@725 120 return;
mas01mj@725 121
mas01mj@725 122 adb_t *handle;
mas01mj@725 123 handle = audiodb_open(pathVal, modeVal);
mas01mj@724 124 jclass adbClass = (*env)->GetObjectClass(env, obj);
mas01mj@724 125 jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J");
mas01mj@724 126 if(fid == NULL) {
mas01mj@724 127 return;
mas01mj@724 128 }
mas01mj@724 129 (*env)->SetLongField(env, obj, fid, (long)handle);
mas01mj@724 130 (*env)->DeleteLocalRef(env, adbClass);
mas01mj@722 131
mas01mj@722 132 return JNI_TRUE;
mas01mj@722 133 }
mas01mj@722 134
mas01mj@725 135 JNIEXPORT void JNICALL Java_org_omras2_AudioDB_audiodb_1close (JNIEnv *env, jobject obj)
mas01mj@722 136 {
mas01mj@725 137 adb_t *handle = get_handle(env, obj);
mas01mj@725 138 if(!handle)
mas01mj@725 139 return;
mas01mj@725 140
mas01mj@725 141 audiodb_close(handle);
mas01mj@725 142
mas01mj@725 143 jclass adbClass = (*env)->GetObjectClass(env, obj);
mas01mj@725 144 jfieldID fid = (*env)->GetFieldID(env, adbClass, "adbHandle", "J");
mas01mj@725 145
mas01mj@725 146 if(fid == NULL) {
mas01mj@725 147 return;
mas01mj@725 148 }
mas01mj@725 149
mas01mj@725 150 (*env)->SetLongField(env, obj, fid, 0);
mas01mj@725 151 (*env)->DeleteLocalRef(env, adbClass);
mas01mj@725 152 }
mas01mj@725 153
mas01mj@728 154 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1insert_1data(JNIEnv *env, jobject obj, jstring key, int nvectors, int dim, jdoubleArray features, jdoubleArray power, jdoubleArray times)
mas01mj@728 155 {
mas01mj@728 156 adb_t *handle = get_handle(env, obj);
mas01mj@728 157 if(!handle)
mas01mj@728 158 return JNI_FALSE;
mas01mj@728 159
mas01mj@728 160 adb_datum_t* ins = (adb_datum_t *)malloc(sizeof(adb_datum_t));
mas01mj@728 161 if(!features || !key)
mas01mj@728 162 return JNI_FALSE;
mas01mj@728 163
mas01mj@728 164 ins->data = (*env)->GetDoubleArrayElements(env, features, NULL);
mas01mj@728 165 ins->power = NULL;
mas01mj@728 166 ins->times = NULL;
mas01mj@728 167
mas01mj@728 168 if(power)
mas01mj@728 169 ins->power = (*env)->GetDoubleArrayElements(env, power, NULL);
mas01mj@728 170 if(times)
mas01mj@728 171 ins->times = (*env)->GetDoubleArrayElements(env, times, NULL);
mas01mj@728 172
mas01mj@728 173 ins->key = (*env)->GetStringUTFChars(env, key, 0);
mas01mj@728 174 ins->nvectors = nvectors;
mas01mj@728 175 ins->dim = dim;
mas01mj@728 176
mas01mj@728 177 int result = audiodb_insert_datum(handle, ins);
mas01mj@728 178 if(result)
mas01mj@728 179 return JNI_FALSE;
mas01mj@728 180
mas01mj@728 181 return JNI_TRUE;
mas01mj@728 182 }
mas01mj@728 183
mas01mj@725 184 JNIEXPORT jboolean JNICALL Java_org_omras2_AudioDB_audiodb_1insert_1path(JNIEnv *env, jobject obj, jstring key, jstring features, jstring power, jstring times)
mas01mj@725 185 {
mas01mj@725 186 adb_t *handle = get_handle(env, obj);
mas01mj@725 187 if(!handle)
mas01mj@725 188 return JNI_FALSE;
mas01mj@725 189
mas01mj@725 190 adb_insert_t* ins = (adb_insert_t *)malloc(sizeof(adb_insert_t));
mas01mj@725 191 ins->key = NULL;
mas01mj@725 192 ins->features = NULL;
mas01mj@725 193 ins->power = NULL;
mas01mj@725 194 ins->times = NULL;
mas01mj@725 195
mas01mj@725 196 if(key)
mas01mj@725 197 ins->key = (*env)->GetStringUTFChars(env, key, 0);
mas01mj@725 198 if(features)
mas01mj@725 199 ins->features = (*env)->GetStringUTFChars(env, features, 0);
mas01mj@725 200 if(power)
mas01mj@725 201 ins->power = (*env)->GetStringUTFChars(env, power, 0);
mas01mj@725 202 if(times)
mas01mj@725 203 ins->times = (*env)->GetStringUTFChars(env, times, 0);
mas01mj@725 204
mas01mj@725 205 int result = audiodb_insert(handle, ins);
mas01mj@725 206
mas01mj@725 207 if(result)
mas01mj@725 208 return JNI_FALSE;
mas01mj@725 209
mas01mj@725 210 return JNI_TRUE;
mas01mj@722 211 }
mas01mj@722 212
mas01mj@722 213 JNIEXPORT void JNICALL Java_org_omras2_AudioDB_query(JNIEnv *env, jobject obj)
mas01mj@722 214 {
mas01mj@722 215 }
mas01mj@722 216
mas01mj@724 217 JNIEXPORT jobject JNICALL Java_org_omras2_AudioDB_audiodb_1status(JNIEnv *env, jobject obj)
mas01mj@722 218 {
mas01mj@725 219 adb_t *handle = get_handle(env, obj);
mas01mj@725 220 if(!handle)
mas01mj@725 221 return NULL;
mas01mj@724 222 adb_status_t *status;
mas01mj@724 223 status = (adb_status_t *)malloc(sizeof(adb_status_t));
mas01mj@724 224 int flags = audiodb_status(handle, status);
mas01mj@724 225
mas01mj@724 226 jclass statusClass = (*env)->FindClass(env, "org/omras2/Status");
mas01mj@724 227 if(statusClass == NULL) {
mas01mj@724 228 return NULL;
mas01mj@724 229 }
mas01mj@724 230 jmethodID cid = (*env)->GetMethodID(env, statusClass, "<init>", "()V");
mas01mj@724 231 if(cid == NULL) {
mas01mj@724 232 return NULL;
mas01mj@724 233 }
mas01mj@724 234
mas01mj@724 235 jobject result = (*env)->NewObject(env, statusClass, cid);
mas01mj@724 236
mas01mj@725 237 // This needs a macro!
mas01mj@725 238 jfieldID fid = (*env)->GetFieldID(env, statusClass, "numFiles", "I");
mas01mj@725 239 if(fid == NULL) return;
mas01mj@724 240 (*env)->SetIntField(env, result, fid, status->numFiles);
mas01mj@725 241
mas01mj@725 242 fid = (*env)->GetFieldID(env, statusClass, "dim", "I");
mas01mj@725 243 if(fid == NULL) return;
mas01mj@725 244 (*env)->SetIntField(env, result, fid, status->dim);
mas01mj@725 245
mas01mj@725 246 fid = (*env)->GetFieldID(env, statusClass, "dudCount", "I");
mas01mj@725 247 if(fid == NULL) return;
mas01mj@725 248 (*env)->SetIntField(env, result, fid, status->dudCount);
mas01mj@725 249
mas01mj@725 250 fid = (*env)->GetFieldID(env, statusClass, "nullCount", "I");
mas01mj@725 251 if(fid == NULL) return;
mas01mj@725 252 (*env)->SetIntField(env, result, fid, status->nullCount);
mas01mj@725 253
mas01mj@725 254 fid = (*env)->GetFieldID(env, statusClass, "length", "I");
mas01mj@725 255 if(fid == NULL) return;
mas01mj@725 256 (*env)->SetIntField(env, result, fid, status->length);
mas01mj@725 257
mas01mj@725 258 fid = (*env)->GetFieldID(env, statusClass, "dataRegionSize", "I");
mas01mj@725 259 if(fid == NULL) return;
mas01mj@725 260 (*env)->SetIntField(env, result, fid, status->data_region_size);
mas01mj@725 261
mas01mj@725 262 // Flags
mas01mj@725 263
mas01mj@725 264 fid = (*env)->GetFieldID(env, statusClass, "isL2Normed", "Z");
mas01mj@725 265 if(fid == NULL) return;
mas01mj@725 266 (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_L2NORM));
mas01mj@725 267
mas01mj@725 268 fid = (*env)->GetFieldID(env, statusClass, "hasPower", "Z");
mas01mj@725 269 if(fid == NULL) return;
mas01mj@725 270 (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_POWER));
mas01mj@725 271
mas01mj@725 272 fid = (*env)->GetFieldID(env, statusClass, "hasTimes", "Z");
mas01mj@725 273 if(fid == NULL) return;
mas01mj@725 274 (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_TIMES));
mas01mj@725 275
mas01mj@725 276 fid = (*env)->GetFieldID(env, statusClass, "hasReferences", "Z");
mas01mj@725 277 if(fid == NULL) return;
mas01mj@725 278 (*env)->SetBooleanField(env, result, fid, (status->flags & ADB_HEADER_FLAG_REFERENCES));
mas01mj@724 279
mas01mj@724 280 (*env)->DeleteLocalRef(env, statusClass);
mas01mj@724 281
mas01mj@724 282 return result;
mas01mj@722 283 }
mas01mj@722 284
mas01mj@727 285 jobject build_results(JNIEnv *env, adb_query_results_t *result)
mas01mj@727 286 {
mas01mj@727 287 int i;
mas01mj@727 288 // Create a vector
mas01mj@727 289 jclass vectorClass = (*env)->FindClass(env, "java/util/Vector");
mas01mj@727 290 if(vectorClass == NULL) return;
mas01mj@727 291 jmethodID vectorCtor = (*env)->GetMethodID(env, vectorClass, "<init>", "()V");
mas01mj@727 292 if(vectorCtor == NULL) return;
mas01mj@727 293 jobject vector = (*env)->NewObject(env, vectorClass, vectorCtor);
mas01mj@727 294
mas01mj@727 295 jmethodID addElementMethod = (*env)->GetMethodID(env, vectorClass, "addElement", "(Ljava/lang/Object;)V");
mas01mj@727 296 if(addElementMethod == NULL) return;
mas01mj@727 297
mas01mj@727 298 jclass resultClass = (*env)->FindClass(env, "org/omras2/Result");
mas01mj@727 299 if(resultClass == NULL) return;
mas01mj@727 300 jmethodID resultCtor = (*env)->GetMethodID(env, resultClass, "<init>", "(Ljava/lang/String;DII)V");
mas01mj@727 301 if(resultCtor == NULL) return;
mas01mj@727 302
mas01mj@727 303 for(i=0; i<result->nresults; i++)
mas01mj@727 304 {
mas01mj@727 305 jstring keyStr = (*env)->NewStringUTF(env, result->results[i].ikey);
mas01mj@727 306 jobject resultObj = (*env)->NewObject(env, resultClass, resultCtor,
mas01mj@727 307 keyStr,
mas01mj@727 308 (double)(result->results[i].dist),
mas01mj@727 309 (int)(result->results[i].qpos),
mas01mj@727 310 (int)(result->results[i].ipos));
mas01mj@727 311
mas01mj@727 312 (*env)->CallObjectMethod(env, vector, addElementMethod, resultObj);
mas01mj@727 313
mas01mj@727 314 }
mas01mj@727 315 (*env)->DeleteLocalRef(env, resultClass);
mas01mj@727 316 (*env)->DeleteLocalRef(env, vectorClass);
mas01mj@727 317 return vector;
mas01mj@727 318 }
mas01mj@727 319
mas01mj@729 320 JNIEXPORT jobject JNICALL Java_org_omras2_AudioDB_audiodb_1query(JNIEnv *env, jobject adbobj, jstring key, jobject queryObject)
mas01mj@726 321 {
mas01mj@726 322 adb_t* handle = get_handle(env, adbobj);
mas01mj@726 323
mas01mj@726 324 if(!handle)
mas01mj@726 325 return;
mas01mj@726 326
mas01mj@729 327 jclass queryClass = (*env)->GetObjectClass(env, queryObject);
mas01mj@726 328
mas01mj@729 329 jclass datumClass = (*env)->FindClass(env, "org/omras2/Datum");
mas01mj@729 330 jfieldID datumFid = (*env)->GetFieldID(env, queryClass, "datum", "Lorg/omras2/Datum;");
mas01mj@729 331 if(datumFid == NULL) return;
mas01mj@729 332
mas01mj@729 333 jobject datumObject = (*env)->GetObjectField(env, queryObject, datumFid);
mas01mj@729 334 if(datumObject == NULL) return;
mas01mj@729 335
mas01mj@726 336 adb_query_spec_t* spec = (adb_query_spec_t *)malloc(sizeof(adb_query_spec_t));
mas01mj@726 337 spec->qid.datum = (adb_datum_t *)malloc(sizeof(adb_datum_t));
mas01mj@726 338 adb_query_results_t* result = (adb_query_results_t *)malloc(sizeof(adb_query_results_t));
mas01mj@726 339
mas01mj@726 340 // As in python bindings
mas01mj@726 341 spec->refine.flags = 0;
mas01mj@726 342
mas01mj@726 343 spec->qid.sequence_length = get_int_val(env, queryClass, queryObject, "seqLength", 16);
mas01mj@726 344 spec->qid.sequence_start = get_int_val(env, queryClass, queryObject, "seqStart", 0);
mas01mj@726 345 spec->params.npoints = get_int_val(env, queryClass, queryObject, "npoints", 1);
mas01mj@726 346 spec->params.ntracks = get_int_val(env, queryClass, queryObject, "ntracks", 100);
mas01mj@726 347
mas01mj@726 348 jfieldID fid = (*env)->GetFieldID(env, queryClass, "exhaustive", "Z");
mas01mj@726 349 if(fid == NULL) return;
mas01mj@726 350 if((*env)->GetBooleanField(env, queryObject, fid)) {
mas01mj@726 351 spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_EXHAUSTIVE;
mas01mj@726 352 }
mas01mj@726 353
mas01mj@726 354 fid = (*env)->GetFieldID(env, queryClass, "hasFalsePositives", "Z");
mas01mj@726 355 if(fid == NULL) return;
mas01mj@726 356 if((*env)->GetBooleanField(env, queryObject, fid)) {
mas01mj@726 357 spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_ALLOW_FALSE_POSITIVES;
mas01mj@726 358 }
mas01mj@726 359
mas01mj@726 360 const char* accType = get_enum_val(env, queryClass, queryObject, "accumulation", "org/omras2/Query$Accumulation");
mas01mj@726 361 const char* distType = get_enum_val(env, queryClass, queryObject, "distance", "org/omras2/Query$Distance");
mas01mj@726 362
mas01mj@726 363 if(strcmp(accType, "DB") == 0)
mas01mj@726 364 spec->params.accumulation = ADB_ACCUMULATION_DB;
mas01mj@726 365 else if(strcmp(accType, "PER_TRACK") == 0)
mas01mj@726 366 spec->params.accumulation = ADB_ACCUMULATION_PER_TRACK;
mas01mj@726 367 else if(strcmp(accType, "ONE_TO_ONE") == 0)
mas01mj@726 368 spec->params.accumulation = ADB_ACCUMULATION_ONE_TO_ONE;
mas01mj@726 369 else {
mas01mj@726 370 return;
mas01mj@726 371 }
mas01mj@726 372
mas01mj@726 373 if(strcmp(distType, "DOT_PRODUCT") == 0)
mas01mj@726 374 spec->params.distance = ADB_DISTANCE_DOT_PRODUCT;
mas01mj@726 375 else if(strcmp(distType, "EUCLIDEAN_NORMED") == 0)
mas01mj@726 376 spec->params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED;
mas01mj@726 377 else if(strcmp(distType, "EUCLIDEAN") == 0)
mas01mj@726 378 spec->params.distance = ADB_DISTANCE_EUCLIDEAN;
mas01mj@726 379 else {
mas01mj@726 380 return;
mas01mj@726 381 }
mas01mj@726 382
mas01mj@727 383 int i;
mas01mj@727 384
mas01mj@727 385 fid = (*env)->GetFieldID(env, queryClass, "includeKeys", "[Ljava/lang/String;");
mas01mj@727 386 if(fid == NULL) return;
mas01mj@727 387 jobjectArray includeObj = (jobjectArray)((*env)->GetObjectField(env, queryObject, fid));
mas01mj@727 388 jsize len = (*env)->GetArrayLength(env, includeObj);
mas01mj@727 389
mas01mj@727 390 if(len > 0)
mas01mj@727 391 {
mas01mj@727 392 spec->refine.flags |= ADB_REFINE_INCLUDE_KEYLIST;
mas01mj@727 393 spec->refine.include.nkeys = len;
mas01mj@727 394 spec->refine.include.keys = (const char **)calloc(sizeof(const char *), spec->refine.include.nkeys);
mas01mj@727 395 for(i=0; i<spec->refine.include.nkeys; i++) {
mas01mj@727 396 jstring key = (*env)->GetObjectArrayElement(env, includeObj, i);
mas01mj@727 397 spec->refine.include.keys[i] = (*env)->GetStringUTFChars(env, key, NULL);
mas01mj@727 398 }
mas01mj@727 399 }
mas01mj@727 400
mas01mj@727 401 fid = (*env)->GetFieldID(env, queryClass, "excludeKeys", "[Ljava/lang/String;");
mas01mj@727 402 if(fid == NULL) return;
mas01mj@727 403 jobjectArray excludeObj = (jobjectArray)((*env)->GetObjectField(env, queryObject, fid));
mas01mj@727 404 len = (*env)->GetArrayLength(env, excludeObj);
mas01mj@727 405
mas01mj@727 406 if(len > 0)
mas01mj@727 407 {
mas01mj@727 408 spec->refine.flags |= ADB_REFINE_EXCLUDE_KEYLIST;
mas01mj@727 409 spec->refine.exclude.nkeys = len;
mas01mj@727 410 spec->refine.exclude.keys = (const char **)calloc(sizeof(const char *), spec->refine.exclude.nkeys);
mas01mj@727 411 for(i=0; i<spec->refine.exclude.nkeys; i++) {
mas01mj@727 412 jstring key = (*env)->GetObjectArrayElement(env, excludeObj, i);
mas01mj@727 413 spec->refine.exclude.keys[i] = (*env)->GetStringUTFChars(env, key, NULL);
mas01mj@727 414 }
mas01mj@727 415 }
mas01mj@727 416
mas01mj@726 417 // Rest of refine
mas01mj@726 418
mas01mj@726 419 double radius = get_double_val(env, queryClass, queryObject, "radius", 0);
mas01mj@726 420 double absThres = get_double_val(env, queryClass, queryObject, "absThres", 0);
mas01mj@726 421 double relThres = get_double_val(env, queryClass, queryObject, "relThres", 0);
mas01mj@726 422 double durRatio = get_double_val(env, queryClass, queryObject, "durRatio", 0);
mas01mj@726 423 int hopSize = get_int_val(env, queryClass, queryObject, "hopSize", 0);
mas01mj@726 424
mas01mj@726 425 if(radius) {
mas01mj@726 426 spec->refine.flags |= ADB_REFINE_RADIUS;
mas01mj@726 427 spec->refine.radius = radius;
mas01mj@726 428 }
mas01mj@726 429
mas01mj@726 430 if(absThres) {
mas01mj@726 431 spec->refine.flags |= ADB_REFINE_ABSOLUTE_THRESHOLD;
mas01mj@726 432 spec->refine.absolute_threshold = absThres;
mas01mj@726 433 }
mas01mj@726 434
mas01mj@726 435 if(relThres) {
mas01mj@726 436 spec->refine.flags |= ADB_REFINE_RELATIVE_THRESHOLD;
mas01mj@726 437 spec->refine.relative_threshold = relThres;
mas01mj@726 438 }
mas01mj@726 439
mas01mj@726 440 if(durRatio) {
mas01mj@726 441 spec->refine.flags |= ADB_REFINE_DURATION_RATIO;
mas01mj@726 442 spec->refine.duration_ratio = durRatio;
mas01mj@726 443 }
mas01mj@726 444
mas01mj@726 445 if(hopSize) {
mas01mj@726 446 spec->refine.flags |= ADB_REFINE_HOP_SIZE;
mas01mj@726 447 spec->refine.qhopsize = hopSize;
mas01mj@726 448 spec->refine.ihopsize = hopSize;
mas01mj@726 449 }
mas01mj@726 450
mas01mj@726 451 spec->qid.datum->data = NULL;
mas01mj@726 452 spec->qid.datum->power = NULL;
mas01mj@726 453 spec->qid.datum->times = NULL;
mas01mj@726 454
mas01mj@729 455 if (key != NULL)
mas01mj@729 456 {
mas01mj@729 457 const char* keyStr = (*env)->GetStringUTFChars(env, key, NULL);
mas01mj@729 458 if(keyStr != NULL)
mas01mj@729 459 {
mas01mj@729 460 int ok = audiodb_retrieve_datum(handle, keyStr, spec->qid.datum);
mas01mj@729 461 if(ok != 0)
mas01mj@729 462 return;
mas01mj@729 463 }
mas01mj@726 464 }
mas01mj@729 465 else
mas01mj@729 466 {
mas01mj@729 467 jdoubleArray data = get_double_array(env, datumClass, datumObject, "data");
mas01mj@729 468 jdouble *dataBody = (*env)->GetDoubleArrayElements(env, data, 0);
mas01mj@729 469 spec->qid.datum->data = dataBody;
mas01mj@729 470
mas01mj@729 471 jdoubleArray power = get_double_array(env, datumClass, datumObject, "power");
mas01mj@729 472 jdouble *powerBody = (*env)->GetDoubleArrayElements(env, power, 0);
mas01mj@729 473 spec->qid.datum->power = powerBody;
mas01mj@729 474
mas01mj@729 475 jdoubleArray times = get_double_array(env, datumClass, datumObject, "times");
mas01mj@729 476 jdouble *timesBody = (*env)->GetDoubleArrayElements(env, times, 0);
mas01mj@729 477 spec->qid.datum->times = timesBody;
mas01mj@729 478
mas01mj@729 479 spec->qid.datum->nvectors = get_int_val(env, datumClass, datumObject, "nvectors", 0);
mas01mj@729 480 spec->qid.datum->dim = get_int_val(env, datumClass, datumObject, "dim", 0);
mas01mj@729 481
mas01mj@729 482 (*env)->ReleaseDoubleArrayElements(env, data, dataBody, 0);
mas01mj@729 483 (*env)->ReleaseDoubleArrayElements(env, power, powerBody, 0);
mas01mj@729 484 (*env)->ReleaseDoubleArrayElements(env, times, timesBody, 0);
mas01mj@729 485 }
mas01mj@729 486
mas01mj@726 487 result = audiodb_query_spec(handle, spec);
mas01mj@726 488
mas01mj@726 489 if(result == NULL) {
mas01mj@726 490 return;
mas01mj@726 491 }
mas01mj@726 492 (*env)->DeleteLocalRef(env, queryClass);
mas01mj@729 493 (*env)->DeleteLocalRef(env, datumClass);
mas01mj@729 494
mas01mj@727 495
mas01mj@727 496 return build_results(env, result);
mas01mj@726 497 }
mas01mj@726 498