Mercurial > hg > audiodb
comparison query.cpp @ 443:cb44e57a96fa api-inversion
New (internal) function audiodb_query_spec_qpointers()
Intended to replace audioDB::set_up_query and
audioDB::set_up_query_from_key; it isn't yet called, but I want to save
my work now before messing with stuff, because the function itself is
long and complicated: it handles three separate ways of getting data
together (datum provided, key provided + LARGE_ADB, key provided +
!LARGE_ADB).
There is insufficient error checking as yet, but hey.
author | mas01cr |
---|---|
date | Wed, 24 Dec 2008 10:56:33 +0000 |
parents | 5294ea1b1bf2 |
children | 4fe90fd568fc |
comparison
equal
deleted
inserted
replaced
442:16c5c51a4c32 | 443:cb44e57a96fa |
---|---|
302 } | 302 } |
303 | 303 |
304 *timesFile >> next; | 304 *timesFile >> next; |
305 if (!timesFile->eof()) { | 305 if (!timesFile->eof()) { |
306 error("too many timepoints in times file", timesFileName); | 306 error("too many timepoints in times file", timesFileName); |
307 } | |
308 } | |
309 | |
310 static int audiodb_query_spec_qpointers(adb_t *adb, adb_query_spec_t *spec, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) { | |
311 adb_datum_t *datum; | |
312 adb_datum_t d = {0}; | |
313 uint32_t nvectors; | |
314 uint32_t sequence_length; | |
315 uint32_t sequence_start; | |
316 | |
317 datum = spec->qid.datum; | |
318 sequence_length = spec->qid.sequence_length; | |
319 sequence_start = spec->qid.sequence_start; | |
320 | |
321 if(datum->data) { | |
322 if(datum->dim != adb->header->dim) { | |
323 return 1; | |
324 } | |
325 /* initialize d, and mark that nothing needs freeing later. */ | |
326 d = *datum; | |
327 datum = &d; | |
328 } else if (datum->key) { | |
329 std::map<std::string,uint32_t>::iterator it; | |
330 it = adb->keys->find(datum->key); | |
331 if(it == adb->keys->end()) { | |
332 return 1; | |
333 } | |
334 uint32_t track_id = (*it).second; | |
335 off_t track_offset = (*adb->track_offsets)[track_id]; | |
336 | |
337 if(adb->header->flags & O2_FLAG_LARGE_ADB) { | |
338 /* create a reference/insert, then use adb_insert_create_datum() */ | |
339 adb_reference_t reference = {0}; | |
340 char features[MAXSTR], power[MAXSTR], times[MAXSTR]; | |
341 lseek(adb->fd, adb->header->dataOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); | |
342 /* FIXME: learn not to worry and love the bomb^Wbuffer overflow */ | |
343 read(adb->fd, features, MAXSTR); | |
344 reference.features = features; | |
345 if(adb->header->flags & O2_FLAG_POWER) { | |
346 lseek(adb->fd, adb->header->powerTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); | |
347 read(adb->fd, power, MAXSTR); | |
348 reference.power = power; | |
349 } | |
350 if(adb->header->flags & O2_FLAG_TIMES) { | |
351 lseek(adb->fd, adb->header->timesTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); | |
352 read(adb->fd, times, MAXSTR); | |
353 reference.times = times; | |
354 } | |
355 audiodb_insert_create_datum(&reference, &d); | |
356 } else { | |
357 /* initialize from sources of data that we already have */ | |
358 d.nvectors = (*adb->track_lengths)[track_id]; | |
359 d.dim = adb->header->dim; | |
360 d.key = datum->key; | |
361 /* read out stuff from the database tables */ | |
362 d.data = (double *) malloc(d.nvectors * d.dim * sizeof(double)); | |
363 lseek(adb->fd, adb->header->dataOffset + track_offset, SEEK_SET); | |
364 read(adb->fd, d.data, d.nvectors * d.dim * sizeof(double)); | |
365 if(adb->header->flags & O2_FLAG_POWER) { | |
366 d.power = (double *) malloc(d.nvectors * sizeof(double)); | |
367 lseek(adb->fd, adb->header->powerTableOffset + track_offset / d.dim, SEEK_SET); | |
368 read(adb->fd, d.power, d.nvectors * sizeof(double)); | |
369 } | |
370 if(adb->header->flags & O2_FLAG_TIMES) { | |
371 d.times = (double *) malloc(2 * d.nvectors * sizeof(double)); | |
372 lseek(adb->fd, adb->header->timesTableOffset + track_offset / d.dim, SEEK_SET); | |
373 read(adb->fd, d.times, 2 * d.nvectors * sizeof(double)); | |
374 } | |
375 } | |
376 } else { | |
377 return 1; | |
378 } | |
379 | |
380 /* Now we have a full(ish) datum, compute all the qpointery stuff | |
381 that we care about (l2norm/power/mean duration). (This bit could | |
382 conceivably become a new function) */ | |
383 nvectors = d.nvectors; | |
384 if(sequence_start > nvectors - sequence_length) { | |
385 /* is there something to free? goto error */ | |
386 return 1; | |
387 } | |
388 | |
389 qpointers->nvectors = nvectors; | |
390 | |
391 size_t vector_size = nvectors * sizeof(double) * d.dim; | |
392 *vector_data = (double *) malloc(vector_size); | |
393 memcpy(*vector_data, d.data, vector_size); | |
394 | |
395 qpointers->l2norm_data = (double *) malloc(vector_size / d.dim); | |
396 audiodb_l2norm_buffer(*vector_data, d.dim, nvectors, qpointers->l2norm_data); | |
397 audiodb_sequence_sum(qpointers->l2norm_data, nvectors, sequence_length); | |
398 audiodb_sequence_sqrt(qpointers->l2norm_data, nvectors, sequence_length); | |
399 | |
400 if(d.power) { | |
401 qpointers->power_data = (double *) malloc(vector_size / d.dim); | |
402 memcpy(qpointers->power_data, d.power, vector_size / d.dim); | |
403 audiodb_sequence_sum(qpointers->power_data, nvectors, sequence_length); | |
404 audiodb_sequence_average(qpointers->power_data, nvectors, sequence_length); | |
405 } | |
406 | |
407 if(d.times) { | |
408 qpointers->mean_duration = (double *) calloc(1, sizeof(double)); | |
409 for(unsigned int k = 0; k < nvectors; k++) { | |
410 *qpointers->mean_duration += d.times[2*k+1] - d.times[2*k]; | |
411 } | |
412 *qpointers->mean_duration /= nvectors; | |
413 } | |
414 | |
415 | |
416 /* Finally, set up the moving qpointers. */ | |
417 if(spec->qid.flags & ADB_QUERY_ID_FLAG_EXHAUSTIVE) { | |
418 *vector = *vector_data; | |
419 qpointers->l2norm = qpointers->l2norm_data; | |
420 qpointers->power = qpointers->power_data; | |
421 } else { | |
422 *vector = *vector_data + spec->qid.sequence_start * d.dim; | |
423 qpointers->l2norm = qpointers->l2norm_data + spec->qid.sequence_start; | |
424 qpointers->power = qpointers->power_data + spec->qid.sequence_start; | |
425 } | |
426 | |
427 | |
428 /* Clean up: free any bits of datum that we have ourselves | |
429 * allocated. */ | |
430 if(datum != &d) { | |
431 audiodb_free_datum(&d); | |
307 } | 432 } |
308 } | 433 } |
309 | 434 |
310 // These names deserve some unpicking. The names starting with a "q" | 435 // These names deserve some unpicking. The names starting with a "q" |
311 // are pointers to the query, norm and power vectors; the names | 436 // are pointers to the query, norm and power vectors; the names |