Mercurial > hg > audiodb
comparison bindings/python/pyadbmodule.c @ 746:91719fa0d45b
Added _pyadb_retrieveDatum for getting data, powers, or times as a numpy ndarray
author | mas01mc |
---|---|
date | Sat, 20 Nov 2010 15:26:41 +0000 |
parents | 124ae047b968 |
children | fbf16508421f |
comparison
equal
deleted
inserted
replaced
745:6dfde1f7a7eb | 746:91719fa0d45b |
---|---|
13 #include "Python.h" | 13 #include "Python.h" |
14 #include "structmember.h" | 14 #include "structmember.h" |
15 #include "audioDB_API.h" | 15 #include "audioDB_API.h" |
16 #include "numpy/arrayobject.h" | 16 #include "numpy/arrayobject.h" |
17 | 17 |
18 #define ADB_HEADER_FLAG_L2NORM (0x1U) | |
19 #define ADB_HEADER_FLAG_POWER (0x4U) | |
20 #define ADB_HEADER_FLAG_TIMES (0x20U) | |
21 #define ADB_HEADER_FLAG_REFERENCES (0x40U) | |
22 | |
18 static void _pyadb_close(void *ptr); | 23 static void _pyadb_close(void *ptr); |
19 | |
20 | 24 |
21 /* create a new database */ | 25 /* create a new database */ |
22 /* returns a struct or NULL on failure */ | 26 /* returns a struct or NULL on failure */ |
23 /* api call: */ | 27 /* api call: */ |
24 /* adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim);*/ | 28 /* adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim);*/ |
31 ok = PyArg_ParseTuple(args, "sIII", &path, &datasize, &ntracks, &datadim); | 35 ok = PyArg_ParseTuple(args, "sIII", &path, &datasize, &ntracks, &datadim); |
32 if (!ok) return 0; | 36 if (!ok) return 0; |
33 new_database = audiodb_create(path, datasize, ntracks, datadim); | 37 new_database = audiodb_create(path, datasize, ntracks, datadim); |
34 if (!new_database) return 0; | 38 if (!new_database) return 0; |
35 | 39 |
36 return PyCObject_FromVoidPtr( new_database, _pyadb_close); | 40 return PyCObject_FromVoidPtr( new_database, _pyadb_close); |
37 } | 41 } |
38 | 42 |
39 /* open an existing database */ | 43 /* open an existing database */ |
40 /* returns a struct or NULL on failure */ | 44 /* returns a struct or NULL on failure */ |
41 /* flags expects fcntl flags concerning the opening mode */ | 45 /* flags expects fcntl flags concerning the opening mode */ |
573 | 577 |
574 | 578 |
575 } | 579 } |
576 | 580 |
577 | 581 |
582 /* retrieval of inserted data | |
583 * returned numpy array has ndarray.shape = (numVectors, numDims) | |
584 * array datatype needs to be doubles (float may work...) | |
585 * if power reqeusted, it will be a 1d array of length numVectors | |
586 * if times are requested, they will be a 1d array of length 2*nvectors | |
587 */ | |
588 | |
589 // api call: | |
590 // typedef struct adb_datum { | |
591 // uint32_t nvectors; | |
592 // uint32_t dim; | |
593 // const char *key; | |
594 // double *data; | |
595 // double *power; | |
596 // double *times; | |
597 // } adb_datum_t; | |
598 | |
599 //int audiodb_retrieve_datum(adb_t *, const char *, adb_datum_t *); | |
600 //int audiodb_free_datum(adb_t *, adb_datum_t *); | |
601 PyObject * _pyadb_retrieveDatum(PyObject *self, PyObject *args, PyObject *keywds) | |
602 { | |
603 adb_t *current_db = NULL; | |
604 adb_status_t *status = NULL; | |
605 adb_datum_t *ins = NULL; | |
606 int ok=0, errtest=0; | |
607 unsigned features=0, powers=0, times=0; | |
608 PyObject *incoming = 0; // The ADB database | |
609 PyObject *outgoing = 0; // The PyArrayObject | |
610 const char *key = NULL; | |
611 static char *kwlist[] = { "db", "key", "features", "powers", "times", NULL}; | |
612 double * data; | |
613 int dims = 0; | |
614 npy_intp shape[2] = { 0, 0 }; | |
615 | |
616 ok = PyArg_ParseTupleAndKeywords(args, keywds, "Os|III", kwlist, &incoming, &key, &features, &powers, ×); | |
617 if (!ok){ | |
618 PyErr_SetString(PyExc_TypeError, "Failed at PyArg_ParseTupleAndKeywords"); | |
619 return NULL; | |
620 } | |
621 | |
622 if(features+powers+times>1){ | |
623 PyErr_SetString(PyExc_TypeError, "Failed: you must specify only one of features, powers, or times"); | |
624 return NULL; | |
625 } | |
626 | |
627 if(!(features||powers||times)){ | |
628 features=1; // default is to return features | |
629 } | |
630 | |
631 current_db = (adb_t *)PyCObject_AsVoidPtr(incoming); | |
632 if (!current_db){ | |
633 PyErr_SetString(PyExc_TypeError, "Failed to convert open database to C-pointer"); | |
634 return NULL; | |
635 } | |
636 status = (adb_status_t*) malloc(sizeof(adb_status_t)); | |
637 errtest = audiodb_status(current_db, status); | |
638 if(errtest){ | |
639 PyErr_SetString(PyExc_TypeError, "Failed: could not get status of passed ADB database"); | |
640 free(status); | |
641 return NULL; | |
642 } | |
643 | |
644 if(powers && !(status->flags&ADB_HEADER_FLAG_POWER)){ | |
645 PyErr_SetString(PyExc_TypeError, "Failed: powers requested but passed ADB database has no powers"); | |
646 free(status); | |
647 return NULL; | |
648 } | |
649 | |
650 if(times && !(status->flags&ADB_HEADER_FLAG_TIMES)){ | |
651 PyErr_SetString(PyExc_TypeError, "Failed: times requested but passed ADB database has no times"); | |
652 free(status); | |
653 return NULL; | |
654 } | |
655 | |
656 ins = (adb_datum_t *)malloc(sizeof(adb_datum_t)); | |
657 errtest = audiodb_retrieve_datum(current_db, key, ins); // retrieve data from adb via key | |
658 if (errtest){ | |
659 PyErr_SetString(PyExc_TypeError, "Failed to retrieve datum"); | |
660 free(ins); | |
661 return NULL; | |
662 } | |
663 | |
664 if(features){ | |
665 if(ins->dim>1){ | |
666 dims=2; | |
667 shape[1]= ins->dim; | |
668 } | |
669 else{ | |
670 dims=1; | |
671 } | |
672 shape[0]= ins->nvectors; | |
673 data = ins->data; | |
674 } | |
675 else if(powers){ | |
676 dims=1; | |
677 shape[0]= ins->nvectors; | |
678 data = ins->power; | |
679 } | |
680 else if(times){ | |
681 dims=1; | |
682 shape[0]= 2 * ins->nvectors; | |
683 data = ins->times; | |
684 } | |
685 | |
686 outgoing = PyArray_SimpleNewFromData(dims, shape, NPY_DOUBLE, data); | |
687 if (!outgoing){ | |
688 PyErr_SetString(PyExc_TypeError, "Failed to convert retrieved datum to C-Array"); | |
689 return NULL; | |
690 } | |
691 // Apprently Python automatically INCREFs the data pointer, so we don't have to call | |
692 // audiodb_free_datum(current_db, ins); | |
693 free(status); | |
694 free(ins); // free the malloced adb_datum_t structure though | |
695 return outgoing; | |
696 } | |
578 | 697 |
579 | 698 |
580 /* close a database */ | 699 /* close a database */ |
581 /* api call: */ | 700 /* api call: */ |
582 // void audiodb_close(adb_t *db); | 701 // void audiodb_close(adb_t *db); |
608 array given should have ndarray.shape = (numDims*numVectors,)\n\ | 727 array given should have ndarray.shape = (numDims*numVectors,)\n\ |
609 array datatype needs to be doubles (float may work...)\n\ | 728 array datatype needs to be doubles (float may work...)\n\ |
610 if power is given, must be 1d array of length numVectors\n\ | 729 if power is given, must be 1d array of length numVectors\n\ |
611 if times is given, must be 1d array of length 2*numVectors like this:\n\ | 730 if times is given, must be 1d array of length 2*numVectors like this:\n\ |
612 int audiodb_insert_datum(adb_t *, const adb_datum_t *);"}, | 731 int audiodb_insert_datum(adb_t *, const adb_datum_t *);"}, |
732 {"_pyadb_retrieveDatum", (PyCFunction)_pyadb_retrieveDatum, METH_VARARGS | METH_KEYWORDS, "_pyadb_retrieveDatum(adb_t *, key=keystring"}, | |
613 { "_pyadb_insertFromFile", (PyCFunction)_pyadb_insertFromFile, METH_VARARGS | METH_KEYWORDS, | 733 { "_pyadb_insertFromFile", (PyCFunction)_pyadb_insertFromFile, METH_VARARGS | METH_KEYWORDS, |
614 "_pyadb_insertFromFile(adb_t *, features=featureFile, [power=powerfile | key=keystring | times=timingFile])->\ | 734 "_pyadb_insertFromFile(adb_t *, features=featureFile, [power=powerfile | key=keystring | times=timingFile])->\ |
615 int return code (0 for sucess)"}, | 735 int return code (0 for sucess)"}, |
616 { "_pyadb_liszt", (PyCFunction)_pyadb_liszt, METH_VARARGS, | 736 { "_pyadb_liszt", (PyCFunction)_pyadb_liszt, METH_VARARGS, |
617 "_pyadb_liszt(adb_t*)->[[key1,numvecs1],[key2,numvecs2]...]"}, | 737 "_pyadb_liszt(adb_t*)->[[key1,numvecs1],[key2,numvecs2]...]"}, |