ref: bfe8256155757161c8d96033b2c000685a63e001
parent: f2ce0fcdfdf7744b5a730f04f603dfb089110190
author: Paul Brossier <piem@piem.org>
date: Thu Apr 21 17:30:28 EDT 2016
ext/aubio-types.h: rewrite array to fvec conversions to reduce memory allocations
--- a/python/ext/aubio-types.h
+++ b/python/ext/aubio-types.h
@@ -55,13 +55,13 @@
// defined in aubio-proxy.c
extern PyObject *PyAubio_CFvecToArray (fvec_t * self);
-extern fvec_t *PyAubio_ArrayToCFvec (PyObject * self);
+extern int PyAubio_ArrayToCFvec (PyObject * self, fvec_t *out);
-extern Py_cvec *PyAubio_CCvecToPyCvec (cvec_t * self);
-extern cvec_t *PyAubio_ArrayToCCvec (PyObject *input);
+extern PyObject * PyAubio_CCvecToPyCvec (cvec_t * self, Py_cvec *out);
+extern int PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i);
extern PyObject *PyAubio_CFmatToArray (fmat_t * self);
-extern fmat_t *PyAubio_ArrayToCFmat (PyObject *input);
+extern int PyAubio_ArrayToCFmat (PyObject *input, fmat_t *out);
// hand written wrappers
extern PyTypeObject Py_filterType;
--- a/python/ext/aubioproxy.c
+++ b/python/ext/aubioproxy.c
@@ -1,12 +1,17 @@
#include "aubio-types.h"
-fvec_t *
-PyAubio_ArrayToCFvec (PyObject *input) {
- PyObject *array;
- fvec_t *vec;
+PyObject *
+PyAubio_CFvecToArray (fvec_t * self)
+{
+ npy_intp dims[] = { self->length, 1 };
+ return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
+}
+
+int
+PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
if (input == NULL) {
PyErr_SetString (PyExc_ValueError, "input array is not a python object");
- goto fail;
+ return 0;
}
// parsing input object into a Py_fvec
if (PyArray_Check(input)) {
@@ -14,73 +19,62 @@
// we got an array, convert it to an fvec
if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
PyErr_SetString (PyExc_ValueError, "input array is a scalar");
- goto fail;
+ return 0;
} else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
PyErr_SetString (PyExc_ValueError,
"input array has more than one dimensions");
- goto fail;
+ return 0;
}
if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
PyErr_SetString (PyExc_ValueError, "input array should be float");
- goto fail;
+ return 0;
} else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
PyErr_SetString (PyExc_ValueError, "input array should be float32");
- goto fail;
- } else {
- // input data type is float32, nothing else to do
- array = input;
+ return 0;
}
// vec = new_fvec (vec->length);
// no need to really allocate fvec, just its struct member
- vec = (fvec_t *)malloc(sizeof(fvec_t));
- long length = PyArray_SIZE ((PyArrayObject *)array);
- if (length > 0) {
- vec->length = (uint_t)length;
- } else {
+ long length = PyArray_SIZE ((PyArrayObject *)input);
+ if (length <= 0) {
PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
- goto fail;
+ return 0;
}
- vec->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)array, 0);
} else if (PyObject_TypeCheck (input, &PyList_Type)) {
PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
- return NULL;
+ return 0;
} else {
PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
- return NULL;
+ return 0;
}
- return vec;
-
-fail:
- return NULL;
+ out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
+ out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
+ return 1;
}
PyObject *
-PyAubio_CFvecToArray (fvec_t * self)
-{
- npy_intp dims[] = { self->length, 1 };
- return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
-}
-
-Py_cvec *
-PyAubio_CCvecToPyCvec (cvec_t * input) {
- Py_cvec *vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
+PyAubio_CCvecToPyCvec (cvec_t * input, Py_cvec *vec) {
vec->length = input->length;
vec->o = input;
+ // keep a reference to re-use after returning it
Py_INCREF(vec);
- return vec;
+ return (PyObject *)vec;
}
-cvec_t *
-PyAubio_ArrayToCCvec (PyObject *input) {
+int
+PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i) {
if (PyObject_TypeCheck (input, &Py_cvecType)) {
- return ((Py_cvec*)input)->o;
+ //*i = *(((Py_cvec*)input)->o);
+ i->norm = ((Py_cvec*)input)->o->norm;
+ i->phas = ((Py_cvec*)input)->o->phas;
+ i->length = ((Py_cvec*)input)->o->length;
+ return 1;
} else {
PyErr_SetString (PyExc_ValueError, "input array should be float32");
- return NULL;
+ return 0;
}
}
@@ -101,14 +95,12 @@
return array;
}
-fmat_t *
-PyAubio_ArrayToCFmat (PyObject *input) {
- PyObject *array;
- fmat_t *mat;
+int
+PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
uint_t i;
if (input == NULL) {
PyErr_SetString (PyExc_ValueError, "input array is not a python object");
- goto fail;
+ return 0;
}
// parsing input object into a Py_fvec
if (PyArray_Check(input)) {
@@ -116,56 +108,55 @@
// we got an array, convert it to an fvec
if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
PyErr_SetString (PyExc_ValueError, "input array is a scalar");
- goto fail;
+ return 0;
} else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
PyErr_SetString (PyExc_ValueError,
"input array has more than two dimensions");
- goto fail;
+ return 0;
}
if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
PyErr_SetString (PyExc_ValueError, "input array should be float");
- goto fail;
+ return 0;
} else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
PyErr_SetString (PyExc_ValueError, "input array should be float32");
- goto fail;
- } else {
- // input data type is float32, nothing else to do
- array = input;
+ return 0;
}
// no need to really allocate fvec, just its struct member
- mat = (fmat_t *)malloc(sizeof(fmat_t));
- long length = PyArray_DIM ((PyArrayObject *)array, 1);
- if (length > 0) {
- mat->length = (uint_t)length;
- } else {
+ long length = PyArray_DIM ((PyArrayObject *)input, 1);
+ if (length <= 0) {
PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
- goto fail;
+ return 0;
}
- long height = PyArray_DIM ((PyArrayObject *)array, 0);
- if (height > 0) {
- mat->height = (uint_t)height;
- } else {
+ long height = PyArray_DIM ((PyArrayObject *)input, 0);
+ if (height <= 0) {
PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
- goto fail;
+ return 0;
}
- mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
- for (i=0; i< mat->height; i++) {
- mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)array, i);
- }
} else if (PyObject_TypeCheck (input, &PyList_Type)) {
PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
- return NULL;
+ return 0;
} else {
PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
- return NULL;
+ return 0;
}
- return mat;
+ if (mat->height != (uint_t)PyArray_DIM ((PyArrayObject *)input, 0)) {
+ /*
+ free(mat->data);
+ mat->height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0);
+ mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
+ */
+ PyErr_Format(PyExc_ValueError, "too many rows, %d but %ld expected",
+ mat->height, PyArray_DIM ((PyArrayObject *)input, 0) );
+ return 0;
+ }
-fail:
- return NULL;
+ mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1);
+ for (i=0; i< mat->height; i++) {
+ mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i);
+ }
+ return 1;
}
-