Mercurial > hg > audiodb
changeset 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 | 6dfde1f7a7eb |
children | fbf16508421f |
files | bindings/python/pyadbmodule.c |
diffstat | 1 files changed, 122 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/bindings/python/pyadbmodule.c Sun Nov 14 14:12:32 2010 +0000 +++ b/bindings/python/pyadbmodule.c Sat Nov 20 15:26:41 2010 +0000 @@ -15,9 +15,13 @@ #include "audioDB_API.h" #include "numpy/arrayobject.h" +#define ADB_HEADER_FLAG_L2NORM (0x1U) +#define ADB_HEADER_FLAG_POWER (0x4U) +#define ADB_HEADER_FLAG_TIMES (0x20U) +#define ADB_HEADER_FLAG_REFERENCES (0x40U) + static void _pyadb_close(void *ptr); - /* create a new database */ /* returns a struct or NULL on failure */ /* api call: */ @@ -33,7 +37,7 @@ new_database = audiodb_create(path, datasize, ntracks, datadim); if (!new_database) return 0; - return PyCObject_FromVoidPtr( new_database, _pyadb_close); + return PyCObject_FromVoidPtr( new_database, _pyadb_close); } /* open an existing database */ @@ -575,6 +579,121 @@ } +/* retrieval of inserted data +* returned numpy array has ndarray.shape = (numVectors, numDims) +* array datatype needs to be doubles (float may work...) +* if power reqeusted, it will be a 1d array of length numVectors +* if times are requested, they will be a 1d array of length 2*nvectors +*/ + +// api call: +// typedef struct adb_datum { +// uint32_t nvectors; +// uint32_t dim; +// const char *key; +// double *data; +// double *power; +// double *times; +// } adb_datum_t; + +//int audiodb_retrieve_datum(adb_t *, const char *, adb_datum_t *); +//int audiodb_free_datum(adb_t *, adb_datum_t *); +PyObject * _pyadb_retrieveDatum(PyObject *self, PyObject *args, PyObject *keywds) +{ + adb_t *current_db = NULL; + adb_status_t *status = NULL; + adb_datum_t *ins = NULL; + int ok=0, errtest=0; + unsigned features=0, powers=0, times=0; + PyObject *incoming = 0; // The ADB database + PyObject *outgoing = 0; // The PyArrayObject + const char *key = NULL; + static char *kwlist[] = { "db", "key", "features", "powers", "times", NULL}; + double * data; + int dims = 0; + npy_intp shape[2] = { 0, 0 }; + + ok = PyArg_ParseTupleAndKeywords(args, keywds, "Os|III", kwlist, &incoming, &key, &features, &powers, ×); + if (!ok){ + PyErr_SetString(PyExc_TypeError, "Failed at PyArg_ParseTupleAndKeywords"); + return NULL; + } + + if(features+powers+times>1){ + PyErr_SetString(PyExc_TypeError, "Failed: you must specify only one of features, powers, or times"); + return NULL; + } + + if(!(features||powers||times)){ + features=1; // default is to return features + } + + current_db = (adb_t *)PyCObject_AsVoidPtr(incoming); + if (!current_db){ + PyErr_SetString(PyExc_TypeError, "Failed to convert open database to C-pointer"); + return NULL; + } + status = (adb_status_t*) malloc(sizeof(adb_status_t)); + errtest = audiodb_status(current_db, status); + if(errtest){ + PyErr_SetString(PyExc_TypeError, "Failed: could not get status of passed ADB database"); + free(status); + return NULL; + } + + if(powers && !(status->flags&ADB_HEADER_FLAG_POWER)){ + PyErr_SetString(PyExc_TypeError, "Failed: powers requested but passed ADB database has no powers"); + free(status); + return NULL; + } + + if(times && !(status->flags&ADB_HEADER_FLAG_TIMES)){ + PyErr_SetString(PyExc_TypeError, "Failed: times requested but passed ADB database has no times"); + free(status); + return NULL; + } + + ins = (adb_datum_t *)malloc(sizeof(adb_datum_t)); + errtest = audiodb_retrieve_datum(current_db, key, ins); // retrieve data from adb via key + if (errtest){ + PyErr_SetString(PyExc_TypeError, "Failed to retrieve datum"); + free(ins); + return NULL; + } + + if(features){ + if(ins->dim>1){ + dims=2; + shape[1]= ins->dim; + } + else{ + dims=1; + } + shape[0]= ins->nvectors; + data = ins->data; + } + else if(powers){ + dims=1; + shape[0]= ins->nvectors; + data = ins->power; + } + else if(times){ + dims=1; + shape[0]= 2 * ins->nvectors; + data = ins->times; + } + + outgoing = PyArray_SimpleNewFromData(dims, shape, NPY_DOUBLE, data); + if (!outgoing){ + PyErr_SetString(PyExc_TypeError, "Failed to convert retrieved datum to C-Array"); + return NULL; + } + // Apprently Python automatically INCREFs the data pointer, so we don't have to call + // audiodb_free_datum(current_db, ins); + free(status); + free(ins); // free the malloced adb_datum_t structure though + return outgoing; +} /* close a database */ @@ -610,6 +729,7 @@ if power is given, must be 1d array of length numVectors\n\ if times is given, must be 1d array of length 2*numVectors like this:\n\ int audiodb_insert_datum(adb_t *, const adb_datum_t *);"}, + {"_pyadb_retrieveDatum", (PyCFunction)_pyadb_retrieveDatum, METH_VARARGS | METH_KEYWORDS, "_pyadb_retrieveDatum(adb_t *, key=keystring"}, { "_pyadb_insertFromFile", (PyCFunction)_pyadb_insertFromFile, METH_VARARGS | METH_KEYWORDS, "_pyadb_insertFromFile(adb_t *, features=featureFile, [power=powerfile | key=keystring | times=timingFile])->\ int return code (0 for sucess)"},