source: python/ext/aubioproxy.c @ bfe8256

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since bfe8256 was bfe8256, checked in by Paul Brossier <piem@piem.org>, 3 years ago

ext/aubio-types.h: rewrite array to fvec conversions to reduce memory allocations

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[7395ec5]1#include "aubio-types.h"
2
[bfe8256]3PyObject *
4PyAubio_CFvecToArray (fvec_t * self)
5{
6  npy_intp dims[] = { self->length, 1 };
7  return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
8}
9
10int
11PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
[7395ec5]12  if (input == NULL) {
13    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
[bfe8256]14    return 0;
[7395ec5]15  }
16  // parsing input object into a Py_fvec
17  if (PyArray_Check(input)) {
18
[93004d5]19    // we got an array, convert it to an fvec
[1458de5]20    if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
[7395ec5]21      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
[bfe8256]22      return 0;
[1458de5]23    } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
[7395ec5]24      PyErr_SetString (PyExc_ValueError,
25          "input array has more than one dimensions");
[bfe8256]26      return 0;
[7395ec5]27    }
28
[1458de5]29    if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
[7395ec5]30      PyErr_SetString (PyExc_ValueError, "input array should be float");
[bfe8256]31      return 0;
[1458de5]32    } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
[7395ec5]33      PyErr_SetString (PyExc_ValueError, "input array should be float32");
[bfe8256]34      return 0;
[7395ec5]35    }
36
37    // vec = new_fvec (vec->length);
[93004d5]38    // no need to really allocate fvec, just its struct member
[bfe8256]39    long length = PyArray_SIZE ((PyArrayObject *)input);
40    if (length <= 0) {
[3194dca]41      PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
[bfe8256]42      return 0;
[3194dca]43    }
[7395ec5]44
45  } else if (PyObject_TypeCheck (input, &PyList_Type)) {
46    PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
[bfe8256]47    return 0;
[7395ec5]48  } else {
49    PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
[bfe8256]50    return 0;
[7395ec5]51  }
52
[bfe8256]53  out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
54  out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
55  return 1;
[7395ec5]56}
57
58PyObject *
[bfe8256]59PyAubio_CCvecToPyCvec (cvec_t * input, Py_cvec *vec) {
[7395ec5]60  vec->length = input->length;
61  vec->o = input;
[bfe8256]62  // keep a reference to re-use after returning it
[7395ec5]63  Py_INCREF(vec);
[bfe8256]64  return (PyObject *)vec;
[7395ec5]65}
66
[bfe8256]67int
68PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i) {
[7395ec5]69  if (PyObject_TypeCheck (input, &Py_cvecType)) {
[bfe8256]70      //*i = *(((Py_cvec*)input)->o);
71      i->norm = ((Py_cvec*)input)->o->norm;
72      i->phas = ((Py_cvec*)input)->o->phas;
73      i->length = ((Py_cvec*)input)->o->length;
74      return 1;
[7395ec5]75  } else {
76      PyErr_SetString (PyExc_ValueError, "input array should be float32");
[bfe8256]77      return 0;
[7395ec5]78  }
79}
80
81PyObject *
82PyAubio_CFmatToArray (fmat_t * input)
83{
84  PyObject *array = NULL;
85  uint_t i;
86  npy_intp dims[] = { input->length, 1 };
87  PyObject *concat = PyList_New (0), *tmp = NULL;
88  for (i = 0; i < input->height; i++) {
89    tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, input->data[i]);
90    PyList_Append (concat, tmp);
91    Py_DECREF (tmp);
92  }
93  array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
94  Py_DECREF (concat);
95  return array;
96}
97
[bfe8256]98int
99PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
[93004d5]100  uint_t i;
101  if (input == NULL) {
102    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
[bfe8256]103    return 0;
[93004d5]104  }
105  // parsing input object into a Py_fvec
106  if (PyArray_Check(input)) {
107
108    // we got an array, convert it to an fvec
109    if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
110      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
[bfe8256]111      return 0;
[93004d5]112    } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
113      PyErr_SetString (PyExc_ValueError,
114          "input array has more than two dimensions");
[bfe8256]115      return 0;
[93004d5]116    }
117
118    if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
119      PyErr_SetString (PyExc_ValueError, "input array should be float");
[bfe8256]120      return 0;
[93004d5]121    } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
122      PyErr_SetString (PyExc_ValueError, "input array should be float32");
[bfe8256]123      return 0;
[93004d5]124    }
125
126    // no need to really allocate fvec, just its struct member
[bfe8256]127    long length = PyArray_DIM ((PyArrayObject *)input, 1);
128    if (length <= 0) {
[3194dca]129      PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
[bfe8256]130      return 0;
[3194dca]131    }
[bfe8256]132    long height = PyArray_DIM ((PyArrayObject *)input, 0);
133    if (height <= 0) {
[3194dca]134      PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
[bfe8256]135      return 0;
[93004d5]136    }
137
138  } else if (PyObject_TypeCheck (input, &PyList_Type)) {
139    PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
[bfe8256]140    return 0;
[93004d5]141  } else {
142    PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
[bfe8256]143    return 0;
[93004d5]144  }
145
[bfe8256]146  if (mat->height != (uint_t)PyArray_DIM ((PyArrayObject *)input, 0)) {
147    /*
148    free(mat->data);
149    mat->height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0);
150    mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
151    */
152    PyErr_Format(PyExc_ValueError, "too many rows, %d but %ld expected",
153                      mat->height, PyArray_DIM ((PyArrayObject *)input, 0) );
154    return 0;
155  }
[93004d5]156
[bfe8256]157  mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1);
158  for (i=0; i< mat->height; i++) {
159    mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i);
160  }
161  return 1;
[7395ec5]162}
Note: See TracBrowser for help on using the repository browser.