source: interfaces/python/py-cvec.c @ 0f045b2

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

py-fvec.c, py-cvec.c: towards mono

  • Property mode set to 100644
File size: 10.6 KB
Line 
1#include "aubio-types.h"
2
3/* cvec type definition
4
5class cvec():
6    def __init__(self, length = 1024):
7        self.length = length
8        self.norm = array(length)
9        self.phas = array(length)
10
11*/
12
13static char Py_cvec_doc[] = "cvec object";
14
15static PyObject *
16Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
17{
18  int length= 0;
19  Py_cvec *self;
20  static char *kwlist[] = { "length", NULL };
21
22  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
23          &length)) {
24    return NULL;
25  }
26
27
28  self = (Py_cvec *) type->tp_alloc (type, 0);
29
30  self->length = Py_default_vector_length / 2 + 1;
31
32  if (self == NULL) {
33    return NULL;
34  }
35
36  if (length > 0) {
37    self->length = length / 2 + 1;
38  } else if (length < 0) {
39    PyErr_SetString (PyExc_ValueError,
40        "can not use negative number of elements");
41    return NULL;
42  }
43
44  return (PyObject *) self;
45}
46
47static int
48Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
49{
50  self->o = new_cvec ((self->length - 1) * 2);
51  if (self->o == NULL) {
52    return -1;
53  }
54
55  return 0;
56}
57
58static void
59Py_cvec_del (Py_cvec * self)
60{
61  del_cvec (self->o);
62  self->ob_type->tp_free ((PyObject *) self);
63}
64
65static PyObject *
66Py_cvec_repr (Py_cvec * self, PyObject * unused)
67{
68  PyObject *format = NULL;
69  PyObject *args = NULL;
70  PyObject *result = NULL;
71
72  format = PyString_FromString ("aubio cvec of %d elements");
73  if (format == NULL) {
74    goto fail;
75  }
76
77  args = Py_BuildValue ("I", self->length);
78  if (args == NULL) {
79    goto fail;
80  }
81  cvec_print ( self->o );
82
83  result = PyString_Format (format, args);
84
85fail:
86  Py_XDECREF (format);
87  Py_XDECREF (args);
88
89  return result;
90}
91
92Py_cvec *
93PyAubio_ArrayToCvec (PyObject *input) {
94  PyObject *array;
95  Py_cvec *vec;
96  if (input == NULL) {
97    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
98    goto fail;
99  }
100  // parsing input object into a Py_cvec
101  if (PyObject_TypeCheck (input, &Py_cvecType)) {
102    // input is an cvec, nothing else to do
103    vec = (Py_cvec *) input;
104  } else if (PyArray_Check(input)) {
105
106    // we got an array, convert it to an cvec
107    if (PyArray_NDIM (input) == 0) {
108      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
109      goto fail;
110    } else if (PyArray_NDIM (input) > 1) {
111      PyErr_SetString (PyExc_ValueError,
112          "input array has more than one dimensions");
113      goto fail;
114    }
115
116    if (!PyArray_ISFLOAT (input)) {
117      PyErr_SetString (PyExc_ValueError, "input array should be float");
118      goto fail;
119    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
120      PyErr_SetString (PyExc_ValueError, "input array should be float32");
121      goto fail;
122    } else {
123      // input data type is float32, nothing else to do
124      array = input;
125    }
126
127    // create a new cvec object
128    vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); 
129    if (PyArray_NDIM (array) != 2) {
130      PyErr_SetString (PyExc_ValueError,
131          "input array should be have exactly two rows for norm and phas");
132      goto fail;
133    } else {
134      vec->length = PyArray_SIZE (array);
135    }
136
137    // no need to really allocate cvec, just its struct member
138    // vec->o = new_cvec (vec->length);
139    vec->o = (cvec_t *)malloc(sizeof(cvec_t));
140    vec->o->length = vec->length;
141    // have norm and phas point to array rows
142    vec->o->norm = (smpl_t *) PyArray_GETPTR1 (array, 0);
143    vec->o->phas = (smpl_t *) PyArray_GETPTR1 (array, 1);
144
145  } else {
146    PyErr_SetString (PyExc_ValueError, "can only accept array or cvec as input");
147    return NULL;
148  }
149
150  return vec;
151
152fail:
153  return NULL;
154}
155
156PyObject *
157PyAubio_CvecToArray (Py_cvec * self)
158{
159  PyObject *array = NULL;
160  npy_intp dims[] = { self->o->length, 1 };
161  PyObject *concat = PyList_New (0), *tmp = NULL;
162  tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm);
163  PyList_Append (concat, tmp);
164  Py_DECREF (tmp);
165  tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas);
166  PyList_Append (concat, tmp);
167  Py_DECREF (tmp);
168  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
169  Py_DECREF (concat);
170  return array;
171}
172
173PyObject *
174PyAubio_CvecNormToArray (Py_cvec * self)
175{
176  npy_intp dims[] = { self->o->length, 1 };
177  return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm);
178}
179
180
181PyObject *
182PyAubio_CvecPhasToArray (Py_cvec * self)
183{
184  npy_intp dims[] = { self->o->length, 1 };
185  return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas);
186}
187
188PyObject *
189PyAubio_ArrayToCvecPhas (PyObject * self)
190{
191  return NULL;
192}
193
194PyObject *
195Py_cvec_get_norm (Py_cvec * self, void *closure)
196{
197  return PyAubio_CvecNormToArray(self);
198}
199
200PyObject *
201Py_cvec_get_phas (Py_cvec * self, void *closure)
202{
203  return PyAubio_CvecPhasToArray(self);
204}
205
206static int
207Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
208{
209  PyObject * array;
210  if (input == NULL) {
211    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
212    goto fail;
213  }
214  if (PyArray_Check(input)) {
215
216    // we got an array, convert it to a cvec.norm
217    if (PyArray_NDIM (input) == 0) {
218      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
219      goto fail;
220    } else if (PyArray_NDIM (input) > 2) {
221      PyErr_SetString (PyExc_ValueError,
222          "input array has more than two dimensions");
223      goto fail;
224    }
225
226    if (!PyArray_ISFLOAT (input)) {
227      PyErr_SetString (PyExc_ValueError, "input array should be float");
228      goto fail;
229    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
230      PyErr_SetString (PyExc_ValueError, "input array should be float32");
231      goto fail;
232    }
233    array = input;
234
235    // check input array dimensions
236    if (PyArray_NDIM (array) != 1) {
237      PyErr_Format (PyExc_ValueError,
238          "input array has %d dimensions, not 1",
239          PyArray_NDIM (array));
240      goto fail;
241    } else {
242      if (vec->o->length != PyArray_SIZE (array)) {
243          PyErr_Format (PyExc_ValueError,
244                  "input array has length %d, but cvec has length %d",
245                  PyArray_SIZE (array), vec->o->length);
246          goto fail;
247      }
248    }
249
250    vec->o->norm = (smpl_t *) PyArray_GETPTR1 (array, 0);
251
252  } else {
253    PyErr_SetString (PyExc_ValueError, "can only accept array as input");
254    return 1;
255  }
256
257  Py_INCREF(array);
258  return 0;
259
260fail:
261  return 1;
262}
263
264static int
265Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
266{
267  PyObject * array;
268  if (input == NULL) {
269    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
270    goto fail;
271  }
272  if (PyArray_Check(input)) {
273
274    // we got an array, convert it to a cvec.phas
275    if (PyArray_NDIM (input) == 0) {
276      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
277      goto fail;
278    } else if (PyArray_NDIM (input) > 2) {
279      PyErr_SetString (PyExc_ValueError,
280          "input array has more than two dimensions");
281      goto fail;
282    }
283
284    if (!PyArray_ISFLOAT (input)) {
285      PyErr_SetString (PyExc_ValueError, "input array should be float");
286      goto fail;
287    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
288      PyErr_SetString (PyExc_ValueError, "input array should be float32");
289      goto fail;
290    }
291    array = input;
292
293    // check input array dimensions
294    if (PyArray_NDIM (array) != 1) {
295      PyErr_Format (PyExc_ValueError,
296          "input array has %d dimensions, not 1",
297          PyArray_NDIM (array));
298      goto fail;
299    } else {
300      if (vec->o->length != PyArray_SIZE (array)) {
301          PyErr_Format (PyExc_ValueError,
302                  "input array has length %d, but cvec has length %d",
303                  PyArray_SIZE (array), vec->o->length);
304          goto fail;
305      }
306    }
307
308    vec->o->phas = (smpl_t *) PyArray_GETPTR1 (array, 0);
309
310  } else {
311    PyErr_SetString (PyExc_ValueError, "can only accept array as input");
312    return 1;
313  }
314
315  Py_INCREF(array);
316  return 0;
317
318fail:
319  return 1;
320}
321
322static PyMemberDef Py_cvec_members[] = {
323  // TODO remove READONLY flag and define getter/setter
324  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
325      "length attribute"},
326  {NULL}                        /* Sentinel */
327};
328
329static PyMethodDef Py_cvec_methods[] = {
330  {"__array__", (PyCFunction) PyAubio_CvecToArray, METH_NOARGS,
331      "Returns the content of this cvec as a numpy array"},
332  {NULL}
333};
334
335static PyGetSetDef Py_cvec_getseters[] = {
336  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm, 
337      "Content of the magnitude of this cvec",
338      NULL},
339  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas, 
340      "Content of the magnitude of this cvec",
341      NULL},
342  {NULL} /* sentinel */
343};
344
345PyTypeObject Py_cvecType = {
346  PyObject_HEAD_INIT (NULL)
347  0,                            /* ob_size           */
348  "aubio.cvec",                 /* tp_name           */
349  sizeof (Py_cvec),             /* tp_basicsize      */
350  0,                            /* tp_itemsize       */
351  (destructor) Py_cvec_del,     /* tp_dealloc        */
352  0,                            /* tp_print          */
353  0,                            /* tp_getattr        */
354  0,                            /* tp_setattr        */
355  0,                            /* tp_compare        */
356  (reprfunc) Py_cvec_repr,      /* tp_repr           */
357  0,                            /* tp_as_number      */
358  0, //&Py_cvec_tp_as_sequence,      /* tp_as_sequence    */
359  0,                            /* tp_as_mapping     */
360  0,                            /* tp_hash           */
361  0,                            /* tp_call           */
362  0,                            /* tp_str            */
363  0,                            /* tp_getattro       */
364  0,                            /* tp_setattro       */
365  0,                            /* tp_as_buffer      */
366  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
367  Py_cvec_doc,                  /* tp_doc            */
368  0,                            /* tp_traverse       */
369  0,                            /* tp_clear          */
370  0,                            /* tp_richcompare    */
371  0,                            /* tp_weaklistoffset */
372  0,                            /* tp_iter           */
373  0,                            /* tp_iternext       */
374  Py_cvec_methods,              /* tp_methods        */
375  Py_cvec_members,              /* tp_members        */
376  Py_cvec_getseters,            /* tp_getset         */
377  0,                            /* tp_base           */
378  0,                            /* tp_dict           */
379  0,                            /* tp_descr_get      */
380  0,                            /* tp_descr_set      */
381  0,                            /* tp_dictoffset     */
382  (initproc) Py_cvec_init,      /* tp_init           */
383  0,                            /* tp_alloc          */
384  Py_cvec_new,                  /* tp_new            */
385};
Note: See TracBrowser for help on using the repository browser.