summaryrefslogtreecommitdiff
path: root/python/ext/py-cvec.c
diff options
context:
space:
mode:
Diffstat (limited to 'python/ext/py-cvec.c')
-rw-r--r--python/ext/py-cvec.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/python/ext/py-cvec.c b/python/ext/py-cvec.c
new file mode 100644
index 0000000..427cc46
--- /dev/null
+++ b/python/ext/py-cvec.c
@@ -0,0 +1,251 @@
+#include "aubio-types.h"
+
+/* cvec type definition
+
+class cvec():
+ def __new__(self, length = 1024):
+ self.length = length / 2 + 1
+ self.norm = np.zeros(length / 2 + 1)
+ self.phas = np.zeros(length / 2 + 1)
+
+*/
+
+// special python type for cvec
+typedef struct
+{
+ PyObject_HEAD
+ PyObject *norm;
+ PyObject *phas;
+ uint_t length;
+} Py_cvec;
+
+static char Py_cvec_doc[] = "cvec object";
+
+
+PyObject *
+new_py_cvec(uint_t length) {
+ Py_cvec* vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
+ npy_intp dims[] = { length / 2 + 1, 1 };
+ vec->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
+ vec->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
+ vec->length = length / 2 + 1;
+ return (PyObject*)vec;
+}
+
+int
+PyAubio_PyCvecToCCvec (PyObject *input, cvec_t *i) {
+ if (PyObject_TypeCheck (input, &Py_cvecType)) {
+ Py_cvec * in = (Py_cvec *)input;
+ i->norm = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->norm), 0);
+ i->phas = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->phas), 0);
+ i->length = ((Py_cvec*)input)->length;
+ return 1;
+ } else {
+ PyErr_SetString (PyExc_ValueError, "input array should be aubio.cvec");
+ return 0;
+ }
+}
+
+static PyObject *
+Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{
+ int length= 0;
+ Py_cvec *self;
+ static char *kwlist[] = { "length", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
+ &length)) {
+ return NULL;
+ }
+
+ self = (Py_cvec *) type->tp_alloc (type, 0);
+
+ self->length = Py_default_vector_length / 2 + 1;
+
+ if (self == NULL) {
+ return NULL;
+ }
+
+ if (length > 0) {
+ self->length = length / 2 + 1;
+ } else if (length < 0) {
+ PyErr_SetString (PyExc_ValueError,
+ "can not use negative number of elements");
+ return NULL;
+ }
+
+ return (PyObject *) self;
+}
+
+static int
+Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
+{
+ npy_intp dims[] = { self->length, 1 };
+ self->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
+ self->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
+ return 0;
+}
+
+static void
+Py_cvec_del (Py_cvec * self)
+{
+ Py_DECREF(self->norm);
+ Py_DECREF(self->phas);
+ Py_TYPE(self)->tp_free ((PyObject *) self);
+}
+
+static PyObject *
+Py_cvec_repr (Py_cvec * self, PyObject * unused)
+{
+ PyObject *format = NULL;
+ PyObject *args = NULL;
+ PyObject *result = NULL;
+
+ format = PyUnicode_FromString ("aubio cvec of %d elements");
+ if (format == NULL) {
+ goto fail;
+ }
+
+ args = Py_BuildValue ("I", self->length);
+ if (args == NULL) {
+ goto fail;
+ }
+ // hide actual norm / phas content
+
+ result = PyUnicode_Format (format, args);
+
+fail:
+ Py_XDECREF (format);
+ Py_XDECREF (args);
+
+ return result;
+}
+
+PyObject *
+Py_cvec_get_norm (Py_cvec * self, void *closure)
+{
+ // we want self->norm to still exist after our caller return it
+ Py_INCREF(self->norm);
+ return (PyObject*)(self->norm);
+}
+
+PyObject *
+Py_cvec_get_phas (Py_cvec * self, void *closure)
+{
+ // we want self->phas to still exist after our caller return it
+ Py_INCREF(self->phas);
+ return (PyObject *)(self->phas);
+}
+
+static int
+Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
+{
+ npy_intp length;
+ if (!PyAubio_IsValidVector(input)) {
+ return 1;
+ }
+ length = PyArray_SIZE ((PyArrayObject *)input);
+ if (length != vec->length) {
+ PyErr_Format (PyExc_ValueError,
+ "input array has length %ld, but cvec has length %d", length,
+ vec->length);
+ return 1;
+ }
+
+ Py_XDECREF(vec->norm);
+ vec->norm = input;
+ Py_INCREF(vec->norm);
+ return 0;
+}
+
+static int
+Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
+{
+ npy_intp length;
+ if (!PyAubio_IsValidVector(input)) {
+ return 1;
+ }
+ length = PyArray_SIZE ((PyArrayObject *)input);
+ if (length != vec->length) {
+ PyErr_Format (PyExc_ValueError,
+ "input array has length %ld, but cvec has length %d", length,
+ vec->length);
+ return 1;
+ }
+
+ Py_XDECREF(vec->phas);
+ vec->phas = input;
+ Py_INCREF(vec->phas);
+ return 0;
+}
+
+static PyMemberDef Py_cvec_members[] = {
+ // TODO remove READONLY flag and define getter/setter
+ {"length", T_INT, offsetof (Py_cvec, length), READONLY,
+ "length attribute"},
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef Py_cvec_methods[] = {
+ {NULL}
+};
+
+static PyGetSetDef Py_cvec_getseters[] = {
+ {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
+ "Numpy vector of shape (length,) containing the magnitude",
+ NULL},
+ {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
+ "Numpy vector of shape (length,) containing the phase",
+ NULL},
+ {NULL} /* sentinel */
+};
+
+PyTypeObject Py_cvecType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "aubio.cvec", /* tp_name */
+ sizeof (Py_cvec), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor) Py_cvec_del, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) Py_cvec_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, //&Py_cvec_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_cvec_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Py_cvec_methods, /* tp_methods */
+ Py_cvec_members, /* tp_members */
+ Py_cvec_getseters, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc) Py_cvec_init, /* tp_init */
+ 0, /* tp_alloc */
+ Py_cvec_new, /* tp_new */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};