1 #include "aubio-types.h"
3 /* cvec type definition
6 def __init__(self, length = 1024, channels = 1):
8 self.channels = channels
9 self.norm = array(length, channels)
10 self.phas = array(length, channels)
14 static char Py_cvec_doc[] = "cvec object";
17 Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
19 int length= 0, channels = 0;
21 static char *kwlist[] = { "length", "channels", NULL };
23 if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
24 &length, &channels)) {
29 self = (Py_cvec *) type->tp_alloc (type, 0);
31 self->length = Py_default_vector_length;
32 self->channels = Py_default_vector_channels;
39 self->length = length;
40 } else if (length < 0) {
41 PyErr_SetString (PyExc_ValueError,
42 "can not use negative number of elements");
47 self->channels = channels;
48 } else if (channels < 0) {
49 PyErr_SetString (PyExc_ValueError,
50 "can not use negative number of channels");
54 return (PyObject *) self;
58 Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
60 self->o = new_cvec (self->length, self->channels);
61 if (self->o == NULL) {
69 Py_cvec_del (Py_cvec * self)
72 self->ob_type->tp_free ((PyObject *) self);
76 Py_cvec_repr (Py_cvec * self, PyObject * unused)
78 PyObject *format = NULL;
79 PyObject *args = NULL;
80 PyObject *result = NULL;
82 format = PyString_FromString ("aubio cvec of %d elements with %d channels");
87 args = Py_BuildValue ("II", self->length, self->channels);
91 //cvec_print ( self->o );
93 result = PyString_Format (format, args);
103 PyAubio_ArrayToCvec (PyObject *input) {
107 // parsing input object into a Py_cvec
108 if (PyObject_TypeCheck (input, &Py_cvecType)) {
109 // input is an cvec, nothing else to do
110 vec = (Py_cvec *) input;
111 } else if (PyArray_Check(input)) {
113 // we got an array, convert it to an cvec
114 if (PyArray_NDIM (input) == 0) {
115 PyErr_SetString (PyExc_ValueError, "input array is a scalar");
117 } else if (PyArray_NDIM (input) > 2) {
118 PyErr_SetString (PyExc_ValueError,
119 "input array has more than two dimensions");
123 if (!PyArray_ISFLOAT (input)) {
124 PyErr_SetString (PyExc_ValueError, "input array should be float");
127 } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
128 // input data type is not float32, casting
129 array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_NPY_SMPL);
131 PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT");
135 } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
136 PyErr_SetString (PyExc_ValueError, "input array should be float32");
140 // input data type is float32, nothing else to do
144 // create a new cvec object
145 vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
146 if (PyArray_NDIM (array) == 1) {
147 PyErr_SetString (PyExc_ValueError,
148 "input array should be have at least two rows for norm and phas");
150 } else if (PyArray_NDIM (array) == 2) {
152 vec->length = PyArray_SIZE (array);
154 vec->channels = PyArray_DIM (array, 0) / 2;
155 vec->length = PyArray_DIM (array, 1);
158 // no need to really allocate cvec, just its struct member
159 // vec->o = new_cvec (vec->length, vec->channels);
160 vec->o = (cvec_t *)malloc(sizeof(cvec_t));
161 vec->o->length = vec->length; vec->o->channels = vec->channels;
162 vec->o->norm = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
163 vec->o->phas = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
164 // hat data[i] point to array line
165 for (i = 0; i < vec->channels; i+=2) {
166 vec->o->norm[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
167 vec->o->phas[i] = (smpl_t *) PyArray_GETPTR1 (array, i+1);
171 PyErr_SetString (PyExc_ValueError, "can only accept array or cvec as input");
182 PyAubio_CvecToArray (Py_cvec * self)
184 PyObject *array = NULL;
186 npy_intp dims[] = { self->o->length, 1 };
187 PyObject *concat = PyList_New (0), *tmp = NULL;
188 for (i = 0; i < self->channels; i++) {
189 tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
190 PyList_Append (concat, tmp);
192 tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
193 PyList_Append (concat, tmp);
196 array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
202 PyAubio_CvecNormToArray (Py_cvec * self)
204 PyObject *array = NULL;
206 npy_intp dims[] = { self->o->length, 1 };
207 PyObject *concat = PyList_New (0), *tmp = NULL;
208 for (i = 0; i < self->channels; i++) {
209 tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
210 PyList_Append (concat, tmp);
213 array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
219 PyAubio_ArrayToCvecNorm (PyObject * self)
225 PyAubio_CvecPhasToArray (Py_cvec * self)
227 PyObject *array = NULL;
229 npy_intp dims[] = { self->o->length, 1 };
230 PyObject *concat = PyList_New (0), *tmp = NULL;
231 for (i = 0; i < self->channels; i++) {
232 tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
233 PyList_Append (concat, tmp);
236 array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
242 PyAubio_ArrayToCvecPhas (PyObject * self)
248 Py_cvec_get_norm (Py_cvec * self, void *closure)
250 return PyAubio_CvecNormToArray(self);
254 Py_cvec_get_phas (Py_cvec * self, void *closure)
256 return PyAubio_CvecPhasToArray(self);
260 Py_cvec_set_norm (Py_cvec * self, PyObject *value, void * closure)
266 Py_cvec_set_phas (Py_cvec * self, PyObject *value, void * closure)
272 Py_cvec_getchannels (Py_cvec * self)
274 return self->channels;
278 Py_cvec_getitem (Py_cvec * self, Py_ssize_t index)
282 if (index < 0 || index >= self->channels) {
283 PyErr_SetString (PyExc_IndexError, "no such channel");
287 npy_intp dims[] = { self->length, 1 };
288 array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[index]);
293 Py_cvec_setitem (Py_cvec * self, Py_ssize_t index, PyObject * o)
297 if (index < 0 || index >= self->channels) {
298 PyErr_SetString (PyExc_IndexError, "no such channel");
302 array = PyArray_FROM_OT (o, NPY_FLOAT);
304 PyErr_SetString (PyExc_ValueError, "should be an array of float");
308 if (PyArray_NDIM (array) != 1) {
309 PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
313 if (PyArray_SIZE (array) != self->length) {
314 PyErr_SetString (PyExc_ValueError,
315 "should be an array of same length as target cvec");
319 self->o->norm[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
327 static PyMemberDef Py_cvec_members[] = {
328 // TODO remove READONLY flag and define getter/setter
329 {"length", T_INT, offsetof (Py_cvec, length), READONLY,
331 {"channels", T_INT, offsetof (Py_cvec, channels), READONLY,
332 "channels attribute"},
333 {NULL} /* Sentinel */
336 static PyMethodDef Py_cvec_methods[] = {
337 {"__array__", (PyCFunction) PyAubio_CvecToArray, METH_NOARGS,
338 "Returns the content of this cvec as a numpy array"},
340 {"norm", (PyCFunction) PyAubio_CvecNormToArray, METH_NOARGS,
341 "Returns the content of the magnitude of this cvec as a numpy array."},
342 {"phas", (PyCFunction) PyAubio_CvecPhasToArray, METH_NOARGS,
343 "Returns the content of the phase of this cvec as a numpy array."},
348 static PyGetSetDef Py_cvec_getseters[] = {
349 {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
350 "Content of the magnitude of this cvec",
352 {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
353 "Content of the magnitude of this cvec",
355 {NULL} /* sentinel */
358 static PySequenceMethods Py_cvec_tp_as_sequence = {
359 (lenfunc) Py_cvec_getchannels, /* sq_length */
362 (ssizeargfunc) Py_cvec_getitem, /* sq_item */
364 (ssizeobjargproc) Py_cvec_setitem, /* sq_ass_item */
365 0, /* sq_ass_slice */
367 0, /* sq_inplace_concat */
368 0, /* sq_inplace_repeat */
372 PyTypeObject Py_cvecType = {
373 PyObject_HEAD_INIT (NULL)
375 "aubio.cvec", /* tp_name */
376 sizeof (Py_cvec), /* tp_basicsize */
378 (destructor) Py_cvec_del, /* tp_dealloc */
383 (reprfunc) Py_cvec_repr, /* tp_repr */
384 0, /* tp_as_number */
385 &Py_cvec_tp_as_sequence, /* tp_as_sequence */
386 0, /* tp_as_mapping */
392 0, /* tp_as_buffer */
393 Py_TPFLAGS_DEFAULT, /* tp_flags */
394 Py_cvec_doc, /* tp_doc */
397 0, /* tp_richcompare */
398 0, /* tp_weaklistoffset */
401 Py_cvec_methods, /* tp_methods */
402 Py_cvec_members, /* tp_members */
403 Py_cvec_getseters, /* tp_getset */
406 0, /* tp_descr_get */
407 0, /* tp_descr_set */
408 0, /* tp_dictoffset */
409 (initproc) Py_cvec_init, /* tp_init */
411 Py_cvec_new, /* tp_new */