source: interfaces/python/py-cvec.c @ ec1ce52

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since ec1ce52 was 615ac7d, checked in by Paul Brossier <piem@piem.org>, 15 years ago

.

  • Property mode set to 100644
File size: 11.6 KB
RevLine 
[f826349]1#include "aubio-types.h"
2
3/* cvec type definition
4
5class cvec():
6    def __init__(self, length = 1024, channels = 1):
7        self.length = length
8        self.channels = channels
9        self.norm = array(length, channels)
10        self.phas = array(length, channels)
11*/
12
13
14static char Py_cvec_doc[] = "cvec object";
15
16static PyObject *
17Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
18{
19  int length= 0, channels = 0;
20  Py_cvec *self;
21  static char *kwlist[] = { "length", "channels", NULL };
22
23  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
24          &length, &channels)) {
25    return NULL;
26  }
27
28
29  self = (Py_cvec *) type->tp_alloc (type, 0);
30
31  self->length = Py_default_vector_length;
32  self->channels = Py_default_vector_channels;
33
34  if (self == NULL) {
35    return NULL;
36  }
37
38  if (length > 0) {
39    self->length = length;
40  } else if (length < 0) {
41    PyErr_SetString (PyExc_ValueError,
42        "can not use negative number of elements");
43    return NULL;
44  }
45
46  if (channels > 0) {
47    self->channels = channels;
48  } else if (channels < 0) {
49    PyErr_SetString (PyExc_ValueError,
50        "can not use negative number of channels");
51    return NULL;
52  }
53
54  return (PyObject *) self;
55}
56
57static int
58Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
59{
60  self->o = new_cvec (self->length, self->channels);
61  if (self->o == NULL) {
62    return -1;
63  }
64
65  return 0;
66}
67
68static void
69Py_cvec_del (Py_cvec * self)
70{
71  del_cvec (self->o);
72  self->ob_type->tp_free ((PyObject *) self);
73}
74
75static PyObject *
76Py_cvec_repr (Py_cvec * self, PyObject * unused)
77{
78  PyObject *format = NULL;
79  PyObject *args = NULL;
80  PyObject *result = NULL;
81
82  format = PyString_FromString ("aubio cvec of %d elements with %d channels");
83  if (format == NULL) {
84    goto fail;
85  }
86
87  args = Py_BuildValue ("II", self->length, self->channels);
88  if (args == NULL) {
89    goto fail;
90  }
[615ac7d]91  //cvec_print ( self->o );
[f826349]92
93  result = PyString_Format (format, args);
94
95fail:
96  Py_XDECREF (format);
97  Py_XDECREF (args);
98
99  return result;
100}
101
102Py_cvec *
103PyAubio_ArrayToCvec (PyObject *input) {
104  PyObject *array;
105  Py_cvec *vec;
106  uint_t i;
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)) {
112
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");
116      goto fail;
117    } else if (PyArray_NDIM (input) > 2) {
118      PyErr_SetString (PyExc_ValueError,
119          "input array has more than two dimensions");
120      goto fail;
121    }
122
123    if (!PyArray_ISFLOAT (input)) {
124      PyErr_SetString (PyExc_ValueError, "input array should be float");
125      goto fail;
126#if AUBIO_DO_CASTING
[615ac7d]127    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
[f826349]128      // input data type is not float32, casting
[615ac7d]129      array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_NPY_SMPL);
[f826349]130      if (array == NULL) {
131        PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT");
132        goto fail;
133      }
134#else
[615ac7d]135    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
[f826349]136      PyErr_SetString (PyExc_ValueError, "input array should be float32");
137      goto fail;
138#endif
139    } else {
140      // input data type is float32, nothing else to do
141      array = input;
142    }
143
144    // create a new cvec object
145    vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); 
146    if (PyArray_NDIM (array) == 1) {
[615ac7d]147      PyErr_SetString (PyExc_ValueError,
148          "input array should be have at least two rows for norm and phas");
149      goto fail;
150    } else if (PyArray_NDIM (array) == 2) {
[f826349]151      vec->channels = 1;
152      vec->length = PyArray_SIZE (array);
153    } else {
[615ac7d]154      vec->channels = PyArray_DIM (array, 0) / 2;
[f826349]155      vec->length = PyArray_DIM (array, 1);
156    }
157
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
[615ac7d]165    for (i = 0; i < vec->channels; i+=2) {
[f826349]166      vec->o->norm[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
[615ac7d]167      vec->o->phas[i] = (smpl_t *) PyArray_GETPTR1 (array, i+1);
[f826349]168    }
169
170  } else {
171    PyErr_SetString (PyExc_ValueError, "can only accept array or cvec as input");
172    return NULL;
173  }
174
175  return vec;
176
177fail:
178  return NULL;
179}
180
181PyObject *
182PyAubio_CvecToArray (Py_cvec * self)
183{
184  PyObject *array = NULL;
[615ac7d]185  uint_t i;
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);
191    Py_DECREF (tmp);
192    tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
193    PyList_Append (concat, tmp);
194    Py_DECREF (tmp);
195  }
196  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
197  Py_DECREF (concat);
198  return array;
199}
200
201PyObject *
202PyAubio_CvecNormToArray (Py_cvec * self)
203{
204  PyObject *array = NULL;
205  uint_t i;
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);
211    Py_DECREF (tmp);
212  }
213  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
214  Py_DECREF (concat);
215  return array;
216}
217
218PyObject *
219PyAubio_ArrayToCvecNorm (PyObject * self)
220{
221  return NULL;
222}
223
224PyObject *
225PyAubio_CvecPhasToArray (Py_cvec * self)
226{
227  PyObject *array = NULL;
228  uint_t i;
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);
234    Py_DECREF (tmp);
[f826349]235  }
[615ac7d]236  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
237  Py_DECREF (concat);
[f826349]238  return array;
239}
240
[615ac7d]241PyObject *
242PyAubio_ArrayToCvecPhas (PyObject * self)
243{
244  return NULL;
245}
246
247PyObject *
248Py_cvec_get_norm (Py_cvec * self, void *closure)
249{
250  return PyAubio_CvecNormToArray(self);
251}
252
253PyObject *
254Py_cvec_get_phas (Py_cvec * self, void *closure)
255{
256  return PyAubio_CvecPhasToArray(self);
257}
258
259static int
260Py_cvec_set_norm (Py_cvec * self, PyObject *value, void * closure)
261{
262  return 0;
263}
264
265static int
266Py_cvec_set_phas (Py_cvec * self, PyObject *value, void * closure)
267{
268  return 0;
269}
270
[f826349]271static Py_ssize_t
272Py_cvec_getchannels (Py_cvec * self)
273{
274  return self->channels;
275}
276
277static PyObject *
278Py_cvec_getitem (Py_cvec * self, Py_ssize_t index)
279{
280  PyObject *array;
281
282  if (index < 0 || index >= self->channels) {
283    PyErr_SetString (PyExc_IndexError, "no such channel");
284    return NULL;
285  }
286
287  npy_intp dims[] = { self->length, 1 };
288  array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[index]);
289  return array;
290}
291
292static int
293Py_cvec_setitem (Py_cvec * self, Py_ssize_t index, PyObject * o)
294{
295  PyObject *array;
296
297  if (index < 0 || index >= self->channels) {
298    PyErr_SetString (PyExc_IndexError, "no such channel");
299    return -1;
300  }
301
302  array = PyArray_FROM_OT (o, NPY_FLOAT);
303  if (array == NULL) {
304    PyErr_SetString (PyExc_ValueError, "should be an array of float");
305    goto fail;
306  }
307
308  if (PyArray_NDIM (array) != 1) {
309    PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
310    goto fail;
311  }
312
313  if (PyArray_SIZE (array) != self->length) {
314    PyErr_SetString (PyExc_ValueError,
315        "should be an array of same length as target cvec");
316    goto fail;
317  }
318
319  self->o->norm[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
320
321  return 0;
322
323fail:
324  return -1;
325}
326
327static PyMemberDef Py_cvec_members[] = {
328  // TODO remove READONLY flag and define getter/setter
329  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
330      "length attribute"},
331  {"channels", T_INT, offsetof (Py_cvec, channels), READONLY,
332      "channels attribute"},
333  {NULL}                        /* Sentinel */
334};
335
336static PyMethodDef Py_cvec_methods[] = {
[615ac7d]337  {"__array__", (PyCFunction) PyAubio_CvecToArray, METH_NOARGS,
338      "Returns the content of this cvec as a numpy array"},
339/*
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."},
344*/
[f826349]345  {NULL}
346};
347
[615ac7d]348static PyGetSetDef Py_cvec_getseters[] = {
349  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm, 
350      "Content of the magnitude of this cvec",
351      NULL},
352  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas, 
353      "Content of the magnitude of this cvec",
354      NULL},
355  {NULL} /* sentinel */
356};
357
[f826349]358static PySequenceMethods Py_cvec_tp_as_sequence = {
359  (lenfunc) Py_cvec_getchannels,        /* sq_length         */
360  0,                                    /* sq_concat         */
361  0,                                    /* sq_repeat         */
362  (ssizeargfunc) Py_cvec_getitem,       /* sq_item           */
363  0,                                    /* sq_slice          */
364  (ssizeobjargproc) Py_cvec_setitem,    /* sq_ass_item       */
365  0,                                    /* sq_ass_slice      */
366  0,                                    /* sq_contains       */
367  0,                                    /* sq_inplace_concat */
368  0,                                    /* sq_inplace_repeat */
369};
370
371
372PyTypeObject Py_cvecType = {
373  PyObject_HEAD_INIT (NULL)
374  0,                            /* ob_size           */
375  "aubio.cvec",                 /* tp_name           */
376  sizeof (Py_cvec),             /* tp_basicsize      */
377  0,                            /* tp_itemsize       */
378  (destructor) Py_cvec_del,     /* tp_dealloc        */
379  0,                            /* tp_print          */
380  0,                            /* tp_getattr        */
381  0,                            /* tp_setattr        */
382  0,                            /* tp_compare        */
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     */
387  0,                            /* tp_hash           */
388  0,                            /* tp_call           */
389  0,                            /* tp_str            */
390  0,                            /* tp_getattro       */
391  0,                            /* tp_setattro       */
392  0,                            /* tp_as_buffer      */
393  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
394  Py_cvec_doc,                  /* tp_doc            */
395  0,                            /* tp_traverse       */
396  0,                            /* tp_clear          */
397  0,                            /* tp_richcompare    */
398  0,                            /* tp_weaklistoffset */
399  0,                            /* tp_iter           */
400  0,                            /* tp_iternext       */
401  Py_cvec_methods,              /* tp_methods        */
402  Py_cvec_members,              /* tp_members        */
[615ac7d]403  Py_cvec_getseters,            /* tp_getset         */
[f826349]404  0,                            /* tp_base           */
405  0,                            /* tp_dict           */
406  0,                            /* tp_descr_get      */
407  0,                            /* tp_descr_set      */
408  0,                            /* tp_dictoffset     */
409  (initproc) Py_cvec_init,      /* tp_init           */
410  0,                            /* tp_alloc          */
411  Py_cvec_new,                  /* tp_new            */
412};
Note: See TracBrowser for help on using the repository browser.