source: interfaces/python/py-fvec.c @ d57c879

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

interfaces/python: improve draft wrapper alpha_norm example, add some unit tests

  • Property mode set to 100644
File size: 7.3 KB
Line 
1#include "aubio-types.h"
2
3/* fvec type definition
4
5class fvec():
6    def __init__(self, length = 1024, channels = 1):
7        self.length = length
8        self.channels = channels
9        self.data = array(length, channels)
10
11*/
12
13#define Py_fvec_default_length   1024
14#define Py_fvec_default_channels 1
15
16static char Py_fvec_doc[] = "fvec object";
17
18static PyObject *
19Py_fvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
20{
21  int length= 0, channels = 0;
22  Py_fvec *self;
23  static char *kwlist[] = { "length", "channels", NULL };
24
25  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
26          &length, &channels)) {
27    return NULL;
28  }
29
30
31  self = (Py_fvec *) type->tp_alloc (type, 0);
32
33  self->length = Py_fvec_default_length;
34  self->channels = Py_fvec_default_channels;
35
36  if (self == NULL) {
37    return NULL;
38  }
39
40  if (length > 0) {
41    self->length = length;
42  } else if (length < 0) {
43    PyErr_SetString (PyExc_ValueError,
44        "can not use negative number of elements");
45    return NULL;
46  }
47
48  if (channels > 0) {
49    self->channels = channels;
50  } else if (channels < 0) {
51    PyErr_SetString (PyExc_ValueError,
52        "can not use negative number of channels");
53    return NULL;
54  }
55
56
57  return (PyObject *) self;
58}
59
60static int
61Py_fvec_init (Py_fvec * self, PyObject * args, PyObject * kwds)
62{
63  self->o = new_fvec (self->length, self->channels);
64  if (self->o == NULL) {
65    return -1;
66  }
67
68  return 0;
69}
70
71static void
72Py_fvec_del (Py_fvec * self)
73{
74  del_fvec (self->o);
75  self->ob_type->tp_free ((PyObject *) self);
76}
77
78static PyObject *
79Py_fvec_repr (Py_fvec * self, PyObject * unused)
80{
81  PyObject *format = NULL;
82  PyObject *args = NULL;
83  PyObject *result = NULL;
84
85  format = PyString_FromString ("aubio fvec of %d elements with %d channels");
86  if (format == NULL) {
87    goto fail;
88  }
89
90  args = Py_BuildValue ("II", self->length, self->channels);
91  if (args == NULL) {
92    goto fail;
93  }
94
95  result = PyString_Format (format, args);
96
97fail:
98  Py_XDECREF (format);
99  Py_XDECREF (args);
100
101  return result;
102}
103
104static PyObject *
105Py_fvec_print (Py_fvec * self, PyObject * unused)
106{
107  fvec_print (self->o);
108  return Py_None;
109}
110
111static PyObject *
112Py_fvec_array (Py_fvec * self)
113{
114  PyObject *array = NULL;
115  if (self->channels == 1) {
116    npy_intp dims[] = { self->length, 1 };
117    array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[0]);
118  } else {
119    uint_t i;
120    npy_intp dims[] = { self->length, 1 };
121    PyObject *concat = PyList_New (0), *tmp = NULL;
122    for (i = 0; i < self->channels; i++) {
123      tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[i]);
124      PyList_Append (concat, tmp);
125      Py_DECREF (tmp);
126    }
127    array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
128    Py_DECREF (concat);
129  }
130  return array;
131}
132
133static Py_ssize_t
134Py_fvec_getchannels (Py_fvec * self)
135{
136  return self->channels;
137}
138
139static PyObject *
140Py_fvec_getitem (Py_fvec * self, Py_ssize_t index)
141{
142  PyObject *array;
143
144  if (index < 0 || index >= self->channels) {
145    PyErr_SetString (PyExc_IndexError, "no such channel");
146    return NULL;
147  }
148
149  npy_intp dims[] = { self->length, 1 };
150  array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[index]);
151  return array;
152}
153
154static int
155Py_fvec_setitem (Py_fvec * self, Py_ssize_t index, PyObject * o)
156{
157  PyObject *array;
158
159  if (index < 0 || index >= self->channels) {
160    PyErr_SetString (PyExc_IndexError, "no such channel");
161    return -1;
162  }
163
164  array = PyArray_FROM_OT (o, NPY_FLOAT);
165  if (array == NULL) {
166    PyErr_SetString (PyExc_ValueError, "should be an array of float");
167    goto fail;
168  }
169
170  if (PyArray_NDIM (array) != 1) {
171    PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
172    goto fail;
173  }
174
175  if (PyArray_SIZE (array) != self->length) {
176    PyErr_SetString (PyExc_ValueError,
177        "should be an array of same length as target fvec");
178    goto fail;
179  }
180
181  self->o->data[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
182
183  return 0;
184
185fail:
186  return -1;
187}
188
189static PyMemberDef Py_fvec_members[] = {
190  // TODO remove READONLY flag and define getter/setter
191  {"length", T_INT, offsetof (Py_fvec, length), READONLY,
192      "length attribute"},
193  {"channels", T_INT, offsetof (Py_fvec, channels), READONLY,
194      "channels attribute"},
195  {NULL}                        /* Sentinel */
196};
197
198static PyMethodDef Py_fvec_methods[] = {
199  {"dump", (PyCFunction) Py_fvec_print, METH_NOARGS,
200      "Dumps the contents of the vector to stdout."},
201  {"__array__", (PyCFunction) Py_fvec_array, METH_NOARGS,
202      "Returns the first channel as a numpy array."},
203  {NULL}
204};
205
206static PySequenceMethods Py_fvec_tp_as_sequence = {
207  (lenfunc) Py_fvec_getchannels,        /* sq_length         */
208  0,                                    /* sq_concat         */
209  0,                                    /* sq_repeat         */
210  (ssizeargfunc) Py_fvec_getitem,       /* sq_item           */
211  0,                                    /* sq_slice          */
212  (ssizeobjargproc) Py_fvec_setitem,    /* sq_ass_item       */
213  0,                                    /* sq_ass_slice      */
214  0,                                    /* sq_contains       */
215  0,                                    /* sq_inplace_concat */
216  0,                                    /* sq_inplace_repeat */
217};
218
219
220PyTypeObject Py_fvecType = {
221  PyObject_HEAD_INIT (NULL)
222  0,                            /* ob_size           */
223  "fvec",                       /* tp_name           */
224  sizeof (Py_fvec),             /* tp_basicsize      */
225  0,                            /* tp_itemsize       */
226  (destructor) Py_fvec_del,     /* tp_dealloc        */
227  0,                            /* tp_print          */
228  0,                            /* tp_getattr        */
229  0,                            /* tp_setattr        */
230  0,                            /* tp_compare        */
231  (reprfunc) Py_fvec_repr,      /* tp_repr           */
232  0,                            /* tp_as_number      */
233  &Py_fvec_tp_as_sequence,      /* tp_as_sequence    */
234  0,                            /* tp_as_mapping     */
235  0,                            /* tp_hash           */
236  0,                            /* tp_call           */
237  0,                            /* tp_str            */
238  0,                            /* tp_getattro       */
239  0,                            /* tp_setattro       */
240  0,                            /* tp_as_buffer      */
241  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
242  Py_fvec_doc,                  /* tp_doc            */
243  0,                            /* tp_traverse       */
244  0,                            /* tp_clear          */
245  0,                            /* tp_richcompare    */
246  0,                            /* tp_weaklistoffset */
247  0,                            /* tp_iter           */
248  0,                            /* tp_iternext       */
249  Py_fvec_methods,              /* tp_methods        */
250  Py_fvec_members,              /* tp_members        */
251  0,                            /* tp_getset         */
252  0,                            /* tp_base           */
253  0,                            /* tp_dict           */
254  0,                            /* tp_descr_get      */
255  0,                            /* tp_descr_set      */
256  0,                            /* tp_dictoffset     */
257  (initproc) Py_fvec_init,      /* tp_init           */
258  0,                            /* tp_alloc          */
259  Py_fvec_new,                  /* tp_new            */
260};
Note: See TracBrowser for help on using the repository browser.