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
|