Changeset ae6e15c for interfaces
- Timestamp:
- Sep 30, 2009, 5:42:13 PM (15 years ago)
- 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:
- 7ac818f
- Parents:
- 7de4de0
- Location:
- interfaces/python
- Files:
-
- 4 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
interfaces/python/aubiomodule.c
r7de4de0 rae6e15c 1 1 #include <Python.h> 2 # include <structmember.h>2 #define PY_ARRAY_UNIQUE_SYMBOL PyArray_API 3 3 #include <numpy/arrayobject.h> 4 #include <aubio.h>5 4 6 static char aubio_module_doc[] = "Python module for the aubio library"; 5 #include "aubio-types.h" 7 6 8 /* fvec type definition 9 10 class fvec(): 11 def __init__(self, length = 1024, channels = 1): 12 self.length = length 13 self.channels = channels 14 self.data = array(length, channels) 15 16 */ 17 18 #define Py_fvec_default_length 1024 19 #define Py_fvec_default_channels 1 20 21 static char Py_fvec_doc[] = "fvec object"; 22 23 typedef struct 24 { 25 PyObject_HEAD fvec_t * o; 26 uint_t length; 27 uint_t channels; 28 } Py_fvec; 29 30 static PyObject * 31 Py_fvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds) 32 { 33 int length = 0, channels = 0; 34 Py_fvec *self; 35 static char *kwlist[] = { "length", "channels", NULL }; 36 37 if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist, 38 &length, &channels)) { 39 return NULL; 40 } 41 42 43 self = (Py_fvec *) type->tp_alloc (type, 0); 44 45 self->length = Py_fvec_default_length; 46 self->channels = Py_fvec_default_channels; 47 48 if (self == NULL) { 49 return NULL; 50 } 51 52 if (length > 0) { 53 self->length = length; 54 } else if (length < 0) { 55 PyErr_SetString (PyExc_ValueError, 56 "can not use negative number of elements"); 57 return NULL; 58 } 59 60 if (channels > 0) { 61 self->channels = channels; 62 } else if (channels < 0) { 63 PyErr_SetString (PyExc_ValueError, 64 "can not use negative number of channels"); 65 return NULL; 66 } 67 68 69 return (PyObject *) self; 70 } 71 72 static int 73 Py_fvec_init (Py_fvec * self, PyObject * args, PyObject * kwds) 74 { 75 self->o = new_fvec (self->length, self->channels); 76 if (self->o == NULL) { 77 return -1; 78 } 79 80 return 0; 81 } 82 83 static void 84 Py_fvec_del (Py_fvec * self) 85 { 86 del_fvec (self->o); 87 self->ob_type->tp_free ((PyObject *) self); 88 } 89 90 static PyObject * 91 Py_fvec_repr (Py_fvec * self, PyObject * unused) 92 { 93 PyObject *format = NULL; 94 PyObject *args = NULL; 95 PyObject *result = NULL; 96 97 format = PyString_FromString ("aubio fvec of %d elements with %d channels"); 98 if (format == NULL) { 99 goto fail; 100 } 101 102 args = Py_BuildValue ("II", self->length, self->channels); 103 if (args == NULL) { 104 goto fail; 105 } 106 107 result = PyString_Format (format, args); 108 109 fail: 110 Py_XDECREF (format); 111 Py_XDECREF (args); 112 113 return result; 114 } 115 116 static PyObject * 117 Py_fvec_print (Py_fvec * self, PyObject * unused) 118 { 119 fvec_print (self->o); 120 return Py_None; 121 } 122 123 static PyObject * 124 Py_fvec_array (Py_fvec * self) 125 { 126 PyObject *array = NULL; 127 if (self->channels == 1) { 128 npy_intp dims[] = { self->length, 1 }; 129 array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[0]); 130 } else { 131 uint_t i; 132 npy_intp dims[] = { self->length, 1 }; 133 PyObject *concat = PyList_New (0), *tmp = NULL; 134 for (i = 0; i < self->channels; i++) { 135 tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[i]); 136 PyList_Append (concat, tmp); 137 Py_DECREF (tmp); 138 } 139 array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2); 140 Py_DECREF (concat); 141 } 142 return array; 143 } 144 145 static Py_ssize_t 146 Py_fvec_getchannels (Py_fvec * self) 147 { 148 return self->channels; 149 } 150 151 static PyObject * 152 Py_fvec_getitem (Py_fvec * self, Py_ssize_t index) 153 { 154 PyObject *array; 155 156 if (index < 0 || index >= self->channels) { 157 PyErr_SetString (PyExc_IndexError, "no such channel"); 158 return NULL; 159 } 160 161 npy_intp dims[] = { self->length, 1 }; 162 array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[index]); 163 return array; 164 } 165 166 static int 167 Py_fvec_setitem (Py_fvec * self, Py_ssize_t index, PyObject * o) 168 { 169 PyObject *array; 170 171 if (index < 0 || index >= self->channels) { 172 PyErr_SetString (PyExc_IndexError, "no such channel"); 173 return -1; 174 } 175 176 array = PyArray_FROM_OT (o, NPY_FLOAT); 177 if (array == NULL) { 178 PyErr_SetString (PyExc_ValueError, "should be an array of float"); 179 goto fail; 180 } 181 182 if (PyArray_NDIM (array) != 1) { 183 PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array"); 184 goto fail; 185 } 186 187 if (PyArray_SIZE (array) != self->length) { 188 PyErr_SetString (PyExc_ValueError, 189 "should be an array of same length as target fvec"); 190 goto fail; 191 } 192 193 self->o->data[index] = (smpl_t *) PyArray_GETPTR1 (array, 0); 194 195 return 0; 196 197 fail: 198 return -1; 199 } 200 201 static PyMemberDef Py_fvec_members[] = { 202 // TODO remove READONLY flag and define getter/setter 203 {"length", T_INT, offsetof (Py_fvec, length), READONLY, 204 "length attribute"}, 205 {"channels", T_INT, offsetof (Py_fvec, channels), READONLY, 206 "channels attribute"}, 207 {NULL} /* Sentinel */ 208 }; 209 210 static PyMethodDef Py_fvec_methods[] = { 211 {"dump", (PyCFunction) Py_fvec_print, METH_NOARGS, 212 "Dumps the contents of the vector to stdout."}, 213 {"__array__", (PyCFunction) Py_fvec_array, METH_NOARGS, 214 "Returns the first channel as a numpy array."}, 215 {NULL} 216 }; 217 218 static PySequenceMethods Py_fvec_tp_as_sequence = { 219 (lenfunc) Py_fvec_getchannels, /* sq_length */ 220 0, /* sq_concat */ 221 0, /* sq_repeat */ 222 (ssizeargfunc) Py_fvec_getitem, /* sq_item */ 223 0, /* sq_slice */ 224 (ssizeobjargproc) Py_fvec_setitem, /* sq_ass_item */ 225 0, /* sq_ass_slice */ 226 0, /* sq_contains */ 227 0, /* sq_inplace_concat */ 228 0, /* sq_inplace_repeat */ 229 }; 230 231 232 static PyTypeObject Py_fvecType = { 233 PyObject_HEAD_INIT (NULL) 234 0, /* ob_size */ 235 "fvec", /* tp_name */ 236 sizeof (Py_fvec), /* tp_basicsize */ 237 0, /* tp_itemsize */ 238 (destructor) Py_fvec_del, /* tp_dealloc */ 239 0, /* tp_print */ 240 0, /* tp_getattr */ 241 0, /* tp_setattr */ 242 0, /* tp_compare */ 243 (reprfunc) Py_fvec_repr, /* tp_repr */ 244 0, /* tp_as_number */ 245 &Py_fvec_tp_as_sequence, /* tp_as_sequence */ 246 0, /* tp_as_mapping */ 247 0, /* tp_hash */ 248 0, /* tp_call */ 249 0, /* tp_str */ 250 0, /* tp_getattro */ 251 0, /* tp_setattro */ 252 0, /* tp_as_buffer */ 253 Py_TPFLAGS_DEFAULT, /* tp_flags */ 254 Py_fvec_doc, /* tp_doc */ 255 0, /* tp_traverse */ 256 0, /* tp_clear */ 257 0, /* tp_richcompare */ 258 0, /* tp_weaklistoffset */ 259 0, /* tp_iter */ 260 0, /* tp_iternext */ 261 Py_fvec_methods, /* tp_methods */ 262 Py_fvec_members, /* tp_members */ 263 0, /* tp_getset */ 264 0, /* tp_base */ 265 0, /* tp_dict */ 266 0, /* tp_descr_get */ 267 0, /* tp_descr_set */ 268 0, /* tp_dictoffset */ 269 (initproc) Py_fvec_init, /* tp_init */ 270 0, /* tp_alloc */ 271 Py_fvec_new, /* tp_new */ 272 }; 273 274 /* end of fvec type definition */ 7 static char Py_alpha_norm_doc[] = "compute alpha normalisation factor"; 275 8 276 9 static PyObject * 277 10 Py_alpha_norm (PyObject * self, PyObject * args) 278 11 { 12 PyObject *input; 279 13 Py_fvec *vec; 280 14 smpl_t alpha; 281 15 PyObject *result; 16 PyObject *array; 17 uint_t i; 282 18 283 if (!PyArg_ParseTuple (args, "Of:alpha_norm", & vec, &alpha)) {19 if (!PyArg_ParseTuple (args, "Of:alpha_norm", &input, &alpha)) { 284 20 return NULL; 285 21 } 286 22 287 if ( vec== NULL) {23 if (input == NULL) { 288 24 return NULL; 289 25 } 290 26 27 // parsing input object into a Py_fvec 28 if (PyObject_TypeCheck (input, &Py_fvecType)) { 29 // input is an fvec, nothing else to do 30 vec = (Py_fvec *) input; 31 } else if (PyArray_Check(input)) { 32 33 // we got an array, convert it to an fvec 34 if (PyArray_NDIM (input) == 0) { 35 PyErr_SetString (PyExc_ValueError, "input array is a scalar"); 36 goto fail; 37 } else if (PyArray_NDIM (input) > 2) { 38 PyErr_SetString (PyExc_ValueError, "input array has more than two dimensions"); 39 goto fail; 40 } 41 42 if (!PyArray_ISFLOAT (input)) { 43 PyErr_SetString (PyExc_ValueError, "input array should be float"); 44 goto fail; 45 } else if (PyArray_TYPE (input) != NPY_FLOAT) { 46 // input data type is not float32, casting 47 array = PyArray_Cast ( (PyArrayObject*) input, NPY_FLOAT); 48 if (array == NULL) { 49 PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT"); 50 goto fail; 51 } 52 } else { 53 // input data type is float32, nothing else to do 54 array = input; 55 } 56 57 // create a new fvec object 58 vec = (Py_fvec*) PyObject_New (Py_fvec, &Py_fvecType); 59 if (PyArray_NDIM (array) == 1) { 60 vec->channels = 1; 61 vec->length = PyArray_SIZE (array); 62 } else { 63 vec->channels = PyArray_DIM (array, 0); 64 vec->length = PyArray_DIM (array, 1); 65 } 66 67 // FIXME should not need to allocate fvec 68 vec->o = new_fvec (vec->length, vec->channels); 69 for (i = 0; i < vec->channels; i++) { 70 vec->o->data[i] = (smpl_t *) PyArray_GETPTR1 (array, i); 71 } 72 73 } else { 74 PyErr_SetString (PyExc_ValueError, "can only accept array or fvec as input"); 75 return NULL; 76 } 77 78 // compute the function 291 79 result = Py_BuildValue ("f", vec_alpha_norm (vec->o, alpha)); 292 80 if (result == NULL) { … … 296 84 return result; 297 85 86 fail: 87 return NULL; 298 88 } 299 300 static char Py_alpha_norm_doc[] = "compute alpha normalisation factor";301 89 302 90 static PyMethodDef aubio_methods[] = { … … 304 92 {NULL, NULL} /* Sentinel */ 305 93 }; 94 95 static char aubio_module_doc[] = "Python module for the aubio library"; 306 96 307 97 PyMODINIT_FUNC -
interfaces/python/setup.py
r7de4de0 rae6e15c 4 4 ext_modules = [ 5 5 Extension("_aubio", 6 ["aubiomodule.c" ],6 ["aubiomodule.c", "py-fvec.c"], 7 7 include_dirs=['../../build/default/src', '../../src' ], 8 8 library_dirs=['../../build/default/src', '../../src/.libs' ],
Note: See TracChangeset
for help on using the changeset viewer.