annotate bindings/java/ext/libAudioDB_JNI.c @ 727:4d9e4ff0a9cd

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