ref: 0a6c2115562490aff6ef173bff92e28e48444e85
parent: 1094f52d19f00d26a57e43ef2ea5a2b0ead19f85
author: Paul Brossier <piem@piem.org>
date: Tue Sep 29 23:46:35 EDT 2009
added new python interface draft, work in progress
--- /dev/null
+++ b/interfaces/python/aubiomodule.c
@@ -1,0 +1,332 @@
+#include <Python.h>
+#include <structmember.h>
+#include <numpy/arrayobject.h>
+#include <aubio.h>
+
+static char aubio_module_doc[] = "Python module for the aubio library";
+
+/* fvec type definition
+
+class fvec():
+ def __init__(self, length = 1024, channels = 1):
+ self.length = length
+ self.channels = channels
+ self.data = array(length, channels)
+
+*/
+
+#define Py_fvec_default_length 1024
+#define Py_fvec_default_channels 1
+
+static char Py_fvec_doc[] = "fvec object";
+
+typedef struct
+{+ PyObject_HEAD fvec_t * o;
+ uint_t length;
+ uint_t channels;
+} Py_fvec;
+
+static PyObject *
+Py_fvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{+ int length = 0, channels = 0;
+ Py_fvec *self;
+ static char *kwlist[] = { "length", "channels", NULL };+
+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
+ &length, &channels)) {+ return NULL;
+ }
+
+
+ self = (Py_fvec *) type->tp_alloc (type, 0);
+
+ self->length = Py_fvec_default_length;
+ self->channels = Py_fvec_default_channels;
+
+ if (self == NULL) {+ return NULL;
+ }
+
+ if (length > 0) {+ self->length = length;
+ } else if (length < 0) {+ PyErr_SetString (PyExc_ValueError,
+ "can not use negative number of elements");
+ return NULL;
+ }
+
+ if (channels > 0) {+ self->channels = channels;
+ } else if (channels < 0) {+ PyErr_SetString (PyExc_ValueError,
+ "can not use negative number of channels");
+ return NULL;
+ }
+
+
+ return (PyObject *) self;
+}
+
+static int
+Py_fvec_init (Py_fvec * self, PyObject * args, PyObject * kwds)
+{+ self->o = new_fvec (self->length, self->channels);
+ if (self->o == NULL) {+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+Py_fvec_del (Py_fvec * self)
+{+ del_fvec (self->o);
+ self->ob_type->tp_free ((PyObject *) self);
+}
+
+static PyObject *
+Py_fvec_repr (Py_fvec * self, PyObject * unused)
+{+ PyObject *format = NULL;
+ PyObject *args = NULL;
+ PyObject *result = NULL;
+
+ format = PyString_FromString ("aubio fvec of %d elements with %d channels");+ if (format == NULL) {+ goto fail;
+ }
+
+ args = Py_BuildValue ("II", self->length, self->channels);+ if (args == NULL) {+ goto fail;
+ }
+
+ result = PyString_Format (format, args);
+
+fail:
+ Py_XDECREF (format);
+ Py_XDECREF (args);
+
+ return result;
+}
+
+static PyObject *
+Py_fvec_print (Py_fvec * self, PyObject * unused)
+{+ fvec_print (self->o);
+ return Py_None;
+}
+
+static PyObject *
+Py_fvec_array (Py_fvec * self)
+{+ PyObject *array = NULL;
+ if (self->channels == 1) {+ npy_intp dims[] = { self->length, 1 };+ array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[0]);
+ } else {+ uint_t i;
+ npy_intp dims[] = { self->length, 1 };+ PyObject *concat = PyList_New (0), *tmp = NULL;
+ for (i = 0; i < self->channels; i++) {+ tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[i]);
+ PyList_Append (concat, tmp);
+ Py_DECREF (tmp);
+ }
+ array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
+ Py_DECREF (concat);
+ }
+ return array;
+}
+
+static Py_ssize_t
+Py_fvec_getchannels (Py_fvec * self)
+{+ return self->channels;
+}
+
+static PyObject *
+Py_fvec_getitem (Py_fvec * self, Py_ssize_t index)
+{+ PyObject *array;
+
+ if (index < 0 || index >= self->channels) {+ PyErr_SetString (PyExc_IndexError, "no such channel");
+ return NULL;
+ }
+
+ npy_intp dims[] = { self->length, 1 };+ array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[index]);
+ return array;
+}
+
+static int
+Py_fvec_setitem (Py_fvec * self, Py_ssize_t index, PyObject * o)
+{+ PyObject *array;
+
+ if (index < 0 || index >= self->channels) {+ PyErr_SetString (PyExc_IndexError, "no such channel");
+ return -1;
+ }
+
+ array = PyArray_FROM_OT (o, NPY_FLOAT);
+ if (array == NULL) {+ PyErr_SetString (PyExc_ValueError, "should be an array of float");
+ goto fail;
+ }
+
+ if (PyArray_NDIM (array) != 1) {+ PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
+ goto fail;
+ }
+
+ if (PyArray_SIZE (array) != self->length) {+ PyErr_SetString (PyExc_ValueError,
+ "should be an array of same length as target fvec");
+ goto fail;
+ }
+
+ self->o->data[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
+
+ return 0;
+
+fail:
+ return -1;
+}
+
+static PyMemberDef Py_fvec_members[] = {+ // TODO remove READONLY flag and define getter/setter
+ {"length", T_INT, offsetof (Py_fvec, length), READONLY,+ "length attribute"},
+ {"channels", T_INT, offsetof (Py_fvec, channels), READONLY,+ "channels attribute"},
+ {NULL} /* Sentinel */+};
+
+static PyMethodDef Py_fvec_methods[] = {+ {"dump", (PyCFunction) Py_fvec_print, METH_NOARGS,+ "Dumps the contents of the vector to stdout."},
+ {"__array__", (PyCFunction) Py_fvec_array, METH_NOARGS,+ "Returns the first channel as a numpy array."},
+ {NULL}+};
+
+static PySequenceMethods Py_fvec_tp_as_sequence = {+ (lenfunc) Py_fvec_getchannels, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc) Py_fvec_getitem, /* sq_item */
+ 0, /* sq_slice */
+ (ssizeobjargproc) Py_fvec_setitem, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ 0, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+
+static PyTypeObject Py_fvecType = {+ PyObject_HEAD_INIT (NULL)
+ 0, /* ob_size */
+ "fvec", /* tp_name */
+ sizeof (Py_fvec), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) Py_fvec_del, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) Py_fvec_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &Py_fvec_tp_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_fvec_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Py_fvec_methods, /* tp_methods */
+ Py_fvec_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc) Py_fvec_init, /* tp_init */
+ 0, /* tp_alloc */
+ Py_fvec_new, /* tp_new */
+};
+
+/* end of fvec type definition */
+
+static PyObject *
+Py_alpha_norm (PyObject * self, PyObject * args)
+{+ Py_fvec *vec;
+ smpl_t alpha;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple (args, "Of:alpha_norm", &vec, &alpha)) {+ return NULL;
+ }
+
+ if (vec == NULL) {+ return NULL;
+ }
+
+ result = Py_BuildValue ("f", vec_alpha_norm (vec->o, alpha));+ if (result == NULL) {+ return NULL;
+ }
+
+ return result;
+
+}
+
+static char Py_alpha_norm_doc[] = "compute alpha normalisation factor";
+
+static PyMethodDef aubio_methods[] = {+ {"alpha_norm", Py_alpha_norm, METH_VARARGS, Py_alpha_norm_doc},+ {NULL, NULL} /* Sentinel */+};
+
+PyMODINIT_FUNC
+init_aubio (void)
+{+ PyObject *m;
+ int err;
+
+ if (PyType_Ready (&Py_fvecType) < 0) {+ return;
+ }
+
+ err = _import_array ();
+
+ if (err != 0) {+ fprintf (stderr,
+ "Unable to import Numpy C API from aubio module (error %d)\n", err);
+ }
+
+ m = Py_InitModule3 ("_aubio", aubio_methods, aubio_module_doc);+
+ if (m == NULL) {+ return;
+ }
+
+ Py_INCREF (&Py_fvecType);
+ PyModule_AddObject (m, "fvec", (PyObject *) & Py_fvecType);
+}
--- /dev/null
+++ b/interfaces/python/setup.py
@@ -1,0 +1,10 @@
+from distutils.core import setup, Extension
+
+setup(name="_aubio", version="1.0",
+ ext_modules = [
+ Extension("_aubio",+ ["aubiomodule.c"],
+ include_dirs=['../../build/default/src', '../../src' ],
+ library_dirs=['../../build/default/src', '../../src/.libs' ],
+ libraries=['aubio'])])
+
--
⑨