Changeset bfe8256 for python/ext


Ignore:
Timestamp:
Apr 21, 2016, 9:30:28 PM (9 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
Children:
b5bef11
Parents:
f2ce0fc
Message:

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

Location:
python/ext
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/ext/aubio-types.h

    rf2ce0fc rbfe8256  
    5656// defined in aubio-proxy.c
    5757extern PyObject *PyAubio_CFvecToArray (fvec_t * self);
    58 extern fvec_t *PyAubio_ArrayToCFvec (PyObject * self);
     58extern int PyAubio_ArrayToCFvec (PyObject * self, fvec_t *out);
    5959
    60 extern Py_cvec *PyAubio_CCvecToPyCvec (cvec_t * self);
    61 extern cvec_t *PyAubio_ArrayToCCvec (PyObject *input);
     60extern PyObject * PyAubio_CCvecToPyCvec (cvec_t * self, Py_cvec *out);
     61extern int PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i);
    6262
    6363extern PyObject *PyAubio_CFmatToArray (fmat_t * self);
    64 extern fmat_t *PyAubio_ArrayToCFmat (PyObject *input);
     64extern int PyAubio_ArrayToCFmat (PyObject *input, fmat_t *out);
    6565
    6666// hand written wrappers
  • python/ext/aubioproxy.c

    rf2ce0fc rbfe8256  
    11#include "aubio-types.h"
    2 
    3 fvec_t *
    4 PyAubio_ArrayToCFvec (PyObject *input) {
    5   PyObject *array;
    6   fvec_t *vec;
    7   if (input == NULL) {
    8     PyErr_SetString (PyExc_ValueError, "input array is not a python object");
    9     goto fail;
    10   }
    11   // parsing input object into a Py_fvec
    12   if (PyArray_Check(input)) {
    13 
    14     // we got an array, convert it to an fvec
    15     if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
    16       PyErr_SetString (PyExc_ValueError, "input array is a scalar");
    17       goto fail;
    18     } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
    19       PyErr_SetString (PyExc_ValueError,
    20           "input array has more than one dimensions");
    21       goto fail;
    22     }
    23 
    24     if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
    25       PyErr_SetString (PyExc_ValueError, "input array should be float");
    26       goto fail;
    27     } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
    28       PyErr_SetString (PyExc_ValueError, "input array should be float32");
    29       goto fail;
    30     } else {
    31       // input data type is float32, nothing else to do
    32       array = input;
    33     }
    34 
    35     // vec = new_fvec (vec->length);
    36     // no need to really allocate fvec, just its struct member
    37     vec = (fvec_t *)malloc(sizeof(fvec_t));
    38     long length = PyArray_SIZE ((PyArrayObject *)array);
    39     if (length > 0) {
    40       vec->length = (uint_t)length;
    41     } else {
    42       PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
    43       goto fail;
    44     }
    45     vec->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)array, 0);
    46 
    47   } else if (PyObject_TypeCheck (input, &PyList_Type)) {
    48     PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
    49     return NULL;
    50   } else {
    51     PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
    52     return NULL;
    53   }
    54 
    55   return vec;
    56 
    57 fail:
    58   return NULL;
    59 }
    602
    613PyObject *
     
    668}
    679
    68 Py_cvec *
    69 PyAubio_CCvecToPyCvec (cvec_t * input) {
    70   Py_cvec *vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
     10int
     11PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
     12  if (input == NULL) {
     13    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
     14    return 0;
     15  }
     16  // parsing input object into a Py_fvec
     17  if (PyArray_Check(input)) {
     18
     19    // we got an array, convert it to an fvec
     20    if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
     21      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
     22      return 0;
     23    } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
     24      PyErr_SetString (PyExc_ValueError,
     25          "input array has more than one dimensions");
     26      return 0;
     27    }
     28
     29    if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
     30      PyErr_SetString (PyExc_ValueError, "input array should be float");
     31      return 0;
     32    } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
     33      PyErr_SetString (PyExc_ValueError, "input array should be float32");
     34      return 0;
     35    }
     36
     37    // vec = new_fvec (vec->length);
     38    // no need to really allocate fvec, just its struct member
     39    long length = PyArray_SIZE ((PyArrayObject *)input);
     40    if (length <= 0) {
     41      PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
     42      return 0;
     43    }
     44
     45  } else if (PyObject_TypeCheck (input, &PyList_Type)) {
     46    PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
     47    return 0;
     48  } else {
     49    PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
     50    return 0;
     51  }
     52
     53  out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
     54  out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
     55  return 1;
     56}
     57
     58PyObject *
     59PyAubio_CCvecToPyCvec (cvec_t * input, Py_cvec *vec) {
    7160  vec->length = input->length;
    7261  vec->o = input;
     62  // keep a reference to re-use after returning it
    7363  Py_INCREF(vec);
    74   return vec;
     64  return (PyObject *)vec;
    7565}
    7666
    77 cvec_t *
    78 PyAubio_ArrayToCCvec (PyObject *input) {
     67int
     68PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i) {
    7969  if (PyObject_TypeCheck (input, &Py_cvecType)) {
    80       return ((Py_cvec*)input)->o;
     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;
    8175  } else {
    8276      PyErr_SetString (PyExc_ValueError, "input array should be float32");
    83       return NULL;
     77      return 0;
    8478  }
    8579}
     
    10296}
    10397
    104 fmat_t *
    105 PyAubio_ArrayToCFmat (PyObject *input) {
    106   PyObject *array;
    107   fmat_t *mat;
     98int
     99PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
    108100  uint_t i;
    109101  if (input == NULL) {
    110102    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
    111     goto fail;
     103    return 0;
    112104  }
    113105  // parsing input object into a Py_fvec
     
    117109    if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
    118110      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
    119       goto fail;
     111      return 0;
    120112    } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
    121113      PyErr_SetString (PyExc_ValueError,
    122114          "input array has more than two dimensions");
    123       goto fail;
     115      return 0;
    124116    }
    125117
    126118    if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
    127119      PyErr_SetString (PyExc_ValueError, "input array should be float");
    128       goto fail;
     120      return 0;
    129121    } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
    130122      PyErr_SetString (PyExc_ValueError, "input array should be float32");
    131       goto fail;
    132     } else {
    133       // input data type is float32, nothing else to do
    134       array = input;
     123      return 0;
    135124    }
    136125
    137126    // no need to really allocate fvec, just its struct member
    138     mat = (fmat_t *)malloc(sizeof(fmat_t));
    139     long length = PyArray_DIM ((PyArrayObject *)array, 1);
    140     if (length > 0) {
    141       mat->length = (uint_t)length;
    142     } else {
     127    long length = PyArray_DIM ((PyArrayObject *)input, 1);
     128    if (length <= 0) {
    143129      PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
    144       goto fail;
     130      return 0;
    145131    }
    146     long height = PyArray_DIM ((PyArrayObject *)array, 0);
    147     if (height > 0) {
    148       mat->height = (uint_t)height;
    149     } else {
     132    long height = PyArray_DIM ((PyArrayObject *)input, 0);
     133    if (height <= 0) {
    150134      PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
    151       goto fail;
    152     }
    153     mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
    154     for (i=0; i< mat->height; i++) {
    155       mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)array, i);
     135      return 0;
    156136    }
    157137
    158138  } else if (PyObject_TypeCheck (input, &PyList_Type)) {
    159139    PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
    160     return NULL;
     140    return 0;
    161141  } else {
    162142    PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
    163     return NULL;
     143    return 0;
    164144  }
    165145
    166   return mat;
     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  }
    167156
    168 fail:
    169   return NULL;
     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;
    170162}
    171 
Note: See TracChangeset for help on using the changeset viewer.