source: python/ext/py-cvec.c @ e458af4

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5
Last change on this file since e458af4 was 4deb255, checked in by Paul Brossier <piem@piem.org>, 7 years ago

python/ext/py-cvec.c: setters to return a negative value on error (closes #17)

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[f826349]1#include "aubio-types.h"
2
[92a8800]3/* cvec type definition
[f826349]4
5class cvec():
[92a8800]6    def __new__(self, length = 1024):
7        self.length = length / 2 + 1
8        self.norm = np.zeros(length / 2 + 1)
9        self.phas = np.zeros(length / 2 + 1)
[f826349]10
[7a7b00f]11*/
[f826349]12
[92a8800]13// special python type for cvec
14typedef struct
15{
16  PyObject_HEAD
17  PyObject *norm;
18  PyObject *phas;
19  uint_t length;
20} Py_cvec;
21
[f826349]22static char Py_cvec_doc[] = "cvec object";
23
[ede5d38]24
25PyObject *
26new_py_cvec(uint_t length) {
27  Py_cvec* vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
28  npy_intp dims[] = { length / 2 + 1, 1 };
29  vec->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
30  vec->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
31  vec->length = length / 2 + 1;
32  return (PyObject*)vec;
33}
34
[92a8800]35int
36PyAubio_PyCvecToCCvec (PyObject *input, cvec_t *i) {
37  if (PyObject_TypeCheck (input, &Py_cvecType)) {
38      Py_cvec * in = (Py_cvec *)input;
39      i->norm = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->norm), 0);
40      i->phas = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->phas), 0);
41      i->length = ((Py_cvec*)input)->length;
42      return 1;
43  } else {
44      PyErr_SetString (PyExc_ValueError, "input array should be aubio.cvec");
45      return 0;
46  }
47}
48
[f826349]49static PyObject *
50Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
51{
[7a7b00f]52  int length= 0;
[f826349]53  Py_cvec *self;
[7a7b00f]54  static char *kwlist[] = { "length", NULL };
[f826349]55
[7a7b00f]56  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
57          &length)) {
[f826349]58    return NULL;
59  }
60
61  self = (Py_cvec *) type->tp_alloc (type, 0);
62
[eb93592]63  self->length = Py_default_vector_length / 2 + 1;
[f826349]64
65  if (self == NULL) {
66    return NULL;
67  }
68
69  if (length > 0) {
[eb93592]70    self->length = length / 2 + 1;
[f826349]71  } else if (length < 0) {
72    PyErr_SetString (PyExc_ValueError,
73        "can not use negative number of elements");
74    return NULL;
75  }
76
77  return (PyObject *) self;
78}
79
80static int
81Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
82{
[ede5d38]83  npy_intp dims[] = { self->length, 1 };
84  self->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
85  self->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
[f826349]86  return 0;
87}
88
89static void
90Py_cvec_del (Py_cvec * self)
91{
[ede5d38]92  Py_DECREF(self->norm);
93  Py_DECREF(self->phas);
[770b9e7]94  Py_TYPE(self)->tp_free ((PyObject *) self);
[f826349]95}
96
97static PyObject *
98Py_cvec_repr (Py_cvec * self, PyObject * unused)
99{
100  PyObject *format = NULL;
101  PyObject *args = NULL;
102  PyObject *result = NULL;
103
[5c1200a]104  format = PyUnicode_FromString ("aubio cvec of %d elements");
[f826349]105  if (format == NULL) {
106    goto fail;
107  }
108
[7a7b00f]109  args = Py_BuildValue ("I", self->length);
[f826349]110  if (args == NULL) {
111    goto fail;
112  }
[92a8800]113  // hide actual norm / phas content
[f826349]114
[5c1200a]115  result = PyUnicode_Format (format, args);
[f826349]116
117fail:
118  Py_XDECREF (format);
119  Py_XDECREF (args);
120
121  return result;
122}
123
[615ac7d]124PyObject *
125Py_cvec_get_norm (Py_cvec * self, void *closure)
126{
[ede5d38]127  // we want self->norm to still exist after our caller return it
[92a8800]128  Py_INCREF(self->norm);
129  return (PyObject*)(self->norm);
[615ac7d]130}
131
132PyObject *
133Py_cvec_get_phas (Py_cvec * self, void *closure)
134{
[ede5d38]135  // we want self->phas to still exist after our caller return it
[92a8800]136  Py_INCREF(self->phas);
137  return (PyObject *)(self->phas);
[615ac7d]138}
139
140static int
[a8aaef3]141Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
[615ac7d]142{
[a138975]143  npy_intp length;
[34d0c25]144  if (!PyAubio_IsValidVector(input)) {
[4deb255]145    return -1;
[a8aaef3]146  }
[a138975]147  length = PyArray_SIZE ((PyArrayObject *)input);
[34d0c25]148  if (length != vec->length) {
149    PyErr_Format (PyExc_ValueError,
[a203d0e]150        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
[34d0c25]151        vec->length);
[4deb255]152    return -1;
[a8aaef3]153  }
154
[34d0c25]155  Py_XDECREF(vec->norm);
156  vec->norm = input;
157  Py_INCREF(vec->norm);
[615ac7d]158  return 0;
159}
160
161static int
[a8aaef3]162Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
[615ac7d]163{
[a138975]164  npy_intp length;
[34d0c25]165  if (!PyAubio_IsValidVector(input)) {
[4deb255]166    return -1;
[a8aaef3]167  }
[a138975]168  length = PyArray_SIZE ((PyArrayObject *)input);
[34d0c25]169  if (length != vec->length) {
170    PyErr_Format (PyExc_ValueError,
[a203d0e]171        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
[34d0c25]172        vec->length);
[4deb255]173    return -1;
[a8aaef3]174  }
175
[34d0c25]176  Py_XDECREF(vec->phas);
177  vec->phas = input;
178  Py_INCREF(vec->phas);
[615ac7d]179  return 0;
180}
181
[f826349]182static PyMemberDef Py_cvec_members[] = {
183  // TODO remove READONLY flag and define getter/setter
184  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
185      "length attribute"},
186  {NULL}                        /* Sentinel */
187};
188
189static PyMethodDef Py_cvec_methods[] = {
190  {NULL}
191};
192
[615ac7d]193static PyGetSetDef Py_cvec_getseters[] = {
194  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm, 
[474f297]195      "Numpy vector of shape (length,) containing the magnitude",
[615ac7d]196      NULL},
197  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas, 
[474f297]198      "Numpy vector of shape (length,) containing the phase",
[615ac7d]199      NULL},
200  {NULL} /* sentinel */
201};
202
[f826349]203PyTypeObject Py_cvecType = {
[5c1200a]204  PyVarObject_HEAD_INIT(NULL, 0)
[f826349]205  "aubio.cvec",                 /* tp_name           */
206  sizeof (Py_cvec),             /* tp_basicsize      */
207  0,                            /* tp_itemsize       */
208  (destructor) Py_cvec_del,     /* tp_dealloc        */
209  0,                            /* tp_print          */
210  0,                            /* tp_getattr        */
211  0,                            /* tp_setattr        */
212  0,                            /* tp_compare        */
213  (reprfunc) Py_cvec_repr,      /* tp_repr           */
214  0,                            /* tp_as_number      */
[f2ce0fc]215  0, //&Py_cvec_tp_as_sequence, /* tp_as_sequence    */
[f826349]216  0,                            /* tp_as_mapping     */
217  0,                            /* tp_hash           */
218  0,                            /* tp_call           */
219  0,                            /* tp_str            */
220  0,                            /* tp_getattro       */
221  0,                            /* tp_setattro       */
222  0,                            /* tp_as_buffer      */
223  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
224  Py_cvec_doc,                  /* tp_doc            */
225  0,                            /* tp_traverse       */
226  0,                            /* tp_clear          */
227  0,                            /* tp_richcompare    */
228  0,                            /* tp_weaklistoffset */
229  0,                            /* tp_iter           */
230  0,                            /* tp_iternext       */
231  Py_cvec_methods,              /* tp_methods        */
232  Py_cvec_members,              /* tp_members        */
[615ac7d]233  Py_cvec_getseters,            /* tp_getset         */
[f826349]234  0,                            /* tp_base           */
235  0,                            /* tp_dict           */
236  0,                            /* tp_descr_get      */
237  0,                            /* tp_descr_set      */
238  0,                            /* tp_dictoffset     */
239  (initproc) Py_cvec_init,      /* tp_init           */
240  0,                            /* tp_alloc          */
241  Py_cvec_new,                  /* tp_new            */
[0e70ef9]242  0,
243  0,
244  0,
245  0,
246  0,
247  0,
248  0,
249  0,
250  0,
[f826349]251};
Note: See TracBrowser for help on using the repository browser.