source: interfaces/python/py-fmat.c @ c04d250

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

interfaces/python: towards mono

  • Property mode set to 100644
File size: 9.5 KB
Line 
1#include "aubio-types.h"
2
3/* fmat type definition
4
5class fmat():
6    def __init__(self, length = 1024, height = 1):
7        self.length = length
8        self.height = height
9        self.data = array(length, height)
10
11*/
12
13static char Py_fmat_doc[] = "fmat object";
14
15static PyObject *
16Py_fmat_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
17{
18  int length= 0, height = 0;
19  Py_fmat *self;
20  static char *kwlist[] = { "length", "height", NULL };
21
22  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
23          &length, &height)) {
24    return NULL;
25  }
26
27
28  self = (Py_fmat *) type->tp_alloc (type, 0);
29
30  self->length = Py_default_vector_length;
31  self->height = Py_default_vector_height;
32
33  if (self == NULL) {
34    return NULL;
35  }
36
37  if (length > 0) {
38    self->length = length;
39  } else if (length < 0) {
40    PyErr_SetString (PyExc_ValueError,
41        "can not use negative number of elements");
42    return NULL;
43  }
44
45  if (height > 0) {
46    self->height = height;
47  } else if (height < 0) {
48    PyErr_SetString (PyExc_ValueError,
49        "can not use negative number of height");
50    return NULL;
51  }
52
53  return (PyObject *) self;
54}
55
56static int
57Py_fmat_init (Py_fmat * self, PyObject * args, PyObject * kwds)
58{
59  self->o = new_fmat (self->length, self->height);
60  if (self->o == NULL) {
61    return -1;
62  }
63
64  return 0;
65}
66
67static void
68Py_fmat_del (Py_fmat * self)
69{
70  del_fmat (self->o);
71  self->ob_type->tp_free ((PyObject *) self);
72}
73
74static PyObject *
75Py_fmat_repr (Py_fmat * self, PyObject * unused)
76{
77  PyObject *format = NULL;
78  PyObject *args = NULL;
79  PyObject *result = NULL;
80
81  format = PyString_FromString ("aubio fmat of %d elements with %d height");
82  if (format == NULL) {
83    goto fail;
84  }
85
86  args = Py_BuildValue ("II", self->length, self->height);
87  if (args == NULL) {
88    goto fail;
89  }
90  fmat_print ( self->o );
91
92  result = PyString_Format (format, args);
93
94fail:
95  Py_XDECREF (format);
96  Py_XDECREF (args);
97
98  return result;
99}
100
101Py_fmat *
102PyAubio_ArrayTofmat (PyObject *input) {
103  PyObject *array;
104  Py_fmat *vec;
105  uint_t i;
106  if (input == NULL) {
107    PyErr_SetString (PyExc_ValueError, "input array is not a python object");
108    goto fail;
109  }
110  // parsing input object into a Py_fmat
111  if (PyObject_TypeCheck (input, &Py_fmatType)) {
112    // input is an fmat, nothing else to do
113    vec = (Py_fmat *) input;
114  } else if (PyArray_Check(input)) {
115
116    // we got an array, convert it to an fmat
117    if (PyArray_NDIM (input) == 0) {
118      PyErr_SetString (PyExc_ValueError, "input array is a scalar");
119      goto fail;
120    } else if (PyArray_NDIM (input) > 2) {
121      PyErr_SetString (PyExc_ValueError,
122          "input array has more than two dimensions");
123      goto fail;
124    }
125
126    if (!PyArray_ISFLOAT (input)) {
127      PyErr_SetString (PyExc_ValueError, "input array should be float");
128      goto fail;
129    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
130      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;
135    }
136
137    // create a new fmat object
138    vec = (Py_fmat*) PyObject_New (Py_fmat, &Py_fmatType); 
139    if (PyArray_NDIM (array) == 1) {
140      vec->height = 1;
141      vec->length = PyArray_SIZE (array);
142    } else {
143      vec->height = PyArray_DIM (array, 0);
144      vec->length = PyArray_DIM (array, 1);
145    }
146
147    // no need to really allocate fmat, just its struct member
148    // vec->o = new_fmat (vec->length, vec->height);
149    vec->o = (fmat_t *)malloc(sizeof(fmat_t));
150    vec->o->length = vec->length; vec->o->height = vec->height;
151    vec->o->data = (smpl_t**)malloc(vec->o->height * sizeof(smpl_t*));
152    // hat data[i] point to array line
153    for (i = 0; i < vec->height; i++) {
154      vec->o->data[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
155    }
156
157  } else {
158    PyErr_SetString (PyExc_ValueError, "can only accept array or fmat as input");
159    return NULL;
160  }
161
162  return vec;
163
164fail:
165  return NULL;
166}
167
168PyObject *
169PyAubio_CfmatToArray (fmat_t * self)
170{
171  PyObject *array = NULL;
172  uint_t i;
173  npy_intp dims[] = { self->length, 1 };
174  PyObject *concat = PyList_New (0), *tmp = NULL;
175  for (i = 0; i < self->height; i++) {
176    tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data[i]);
177    PyList_Append (concat, tmp);
178    Py_DECREF (tmp);
179  }
180  array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
181  Py_DECREF (concat);
182  return array;
183}
184
185PyObject *
186PyAubio_FmatToArray (Py_fmat * self)
187{
188  PyObject *array = NULL;
189  if (self->height == 1) {
190    npy_intp dims[] = { self->length, 1 };
191    array = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[0]);
192  } else {
193    uint_t i;
194    npy_intp dims[] = { self->length, 1 };
195    PyObject *concat = PyList_New (0), *tmp = NULL;
196    for (i = 0; i < self->height; i++) {
197      tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[i]);
198      PyList_Append (concat, tmp);
199      Py_DECREF (tmp);
200    }
201    array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
202    Py_DECREF (concat);
203  }
204  return array;
205}
206
207static Py_ssize_t
208Py_fmat_get_height (Py_fmat * self)
209{
210  return self->height;
211}
212
213static PyObject *
214Py_fmat_getitem (Py_fmat * self, Py_ssize_t index)
215{
216  PyObject *array;
217
218  if (index < 0 || index >= self->height) {
219    PyErr_SetString (PyExc_IndexError, "no such channel");
220    return NULL;
221  }
222
223  npy_intp dims[] = { self->length, 1 };
224  array = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[index]);
225  return array;
226}
227
228static int
229Py_fmat_setitem (Py_fmat * self, Py_ssize_t index, PyObject * o)
230{
231  PyObject *array;
232
233  if (index < 0 || index >= self->height) {
234    PyErr_SetString (PyExc_IndexError, "no such channel");
235    return -1;
236  }
237
238  array = PyArray_FROM_OT (o, AUBIO_NPY_SMPL);
239  if (array == NULL) {
240    PyErr_SetString (PyExc_ValueError, "should be an array of float");
241    goto fail;
242  }
243
244  if (PyArray_NDIM (array) != 1) {
245    PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
246    goto fail;
247  }
248
249  if (PyArray_SIZE (array) != self->length) {
250    PyErr_SetString (PyExc_ValueError,
251        "should be an array of same length as target fmat");
252    goto fail;
253  }
254
255  self->o->data[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
256
257  return 0;
258
259fail:
260  return -1;
261}
262
263static PyMemberDef Py_fmat_members[] = {
264  // TODO remove READONLY flag and define getter/setter
265  {"length", T_INT, offsetof (Py_fmat, length), READONLY,
266      "length attribute"},
267  {"height", T_INT, offsetof (Py_fmat, height), READONLY,
268      "height attribute"},
269  {NULL}                        /* Sentinel */
270};
271
272static PyMethodDef Py_fmat_methods[] = {
273  {"__array__", (PyCFunction) PyAubio_FmatToArray, METH_NOARGS,
274      "Returns the vector as a numpy array."},
275  {NULL}
276};
277
278static PySequenceMethods Py_fmat_tp_as_sequence = {
279  (lenfunc) Py_fmat_get_height,        /* sq_length         */
280  0,                                    /* sq_concat         */
281  0,                                    /* sq_repeat         */
282  (ssizeargfunc) Py_fmat_getitem,       /* sq_item           */
283  0,                                    /* sq_slice          */
284  (ssizeobjargproc) Py_fmat_setitem,    /* sq_ass_item       */
285  0,                                    /* sq_ass_slice      */
286  0,                                    /* sq_contains       */
287  0,                                    /* sq_inplace_concat */
288  0,                                    /* sq_inplace_repeat */
289};
290
291
292PyTypeObject Py_fmatType = {
293  PyObject_HEAD_INIT (NULL)
294  0,                            /* ob_size           */
295  "aubio.fmat",                 /* tp_name           */
296  sizeof (Py_fmat),             /* tp_basicsize      */
297  0,                            /* tp_itemsize       */
298  (destructor) Py_fmat_del,     /* tp_dealloc        */
299  0,                            /* tp_print          */
300  0,                            /* tp_getattr        */
301  0,                            /* tp_setattr        */
302  0,                            /* tp_compare        */
303  (reprfunc) Py_fmat_repr,      /* tp_repr           */
304  0,                            /* tp_as_number      */
305  &Py_fmat_tp_as_sequence,      /* tp_as_sequence    */
306  0,                            /* tp_as_mapping     */
307  0,                            /* tp_hash           */
308  0,                            /* tp_call           */
309  0,                            /* tp_str            */
310  0,                            /* tp_getattro       */
311  0,                            /* tp_setattro       */
312  0,                            /* tp_as_buffer      */
313  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
314  Py_fmat_doc,                  /* tp_doc            */
315  0,                            /* tp_traverse       */
316  0,                            /* tp_clear          */
317  0,                            /* tp_richcompare    */
318  0,                            /* tp_weaklistoffset */
319  0,                            /* tp_iter           */
320  0,                            /* tp_iternext       */
321  Py_fmat_methods,              /* tp_methods        */
322  Py_fmat_members,              /* tp_members        */
323  0,                            /* tp_getset         */
324  0,                            /* tp_base           */
325  0,                            /* tp_dict           */
326  0,                            /* tp_descr_get      */
327  0,                            /* tp_descr_set      */
328  0,                            /* tp_dictoffset     */
329  (initproc) Py_fmat_init,      /* tp_init           */
330  0,                            /* tp_alloc          */
331  Py_fmat_new,                  /* tp_new            */
332};
Note: See TracBrowser for help on using the repository browser.