source: python/ext/py-cvec.c @ 49688ef

feature/crepe
Last change on this file since 49688ef was 754a987, checked in by Paul Brossier <piem@piem.org>, 6 years ago

[py] py-cvec uses PyLong_FromLong

  • Property mode set to 100644
File size: 7.5 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
[92948ab]22static char Py_cvec_doc[] = ""
23"cvec(size)\n"
24"\n"
[37a6942]25"A container holding spectral data.\n"
[92948ab]26"\n"
[6d8ae981]27"Create one `cvec` to store the spectral information of a window\n"
28"of `size` points. The data will be stored  in two vectors,\n"
29":attr:`phas` and :attr:`norm`, each of shape (:attr:`length`,),\n"
30"with `length = size // 2 + 1`.\n"
[92948ab]31"\n"
32"Parameters\n"
33"----------\n"
34"size: int\n"
35"   Size of spectrum to create.\n"
36"\n"
37"Examples\n"
38"--------\n"
39">>> c = aubio.cvec(1024)\n"
40">>> c\n"
41"aubio cvec of 513 elements\n"
42">>> c.length\n"
43"513\n"
44">>> c.norm.dtype, c.phas.dtype\n"
45"(dtype('float32'), dtype('float32'))\n"
46">>> c.norm.shape, c.phas.shape\n"
47"((513,), (513,))\n"
48"\n"
49"See Also\n"
50"--------\n"
[37a6942]51"fvec, fft, pvoc\n"
[92948ab]52"";
[f826349]53
[ede5d38]54
55PyObject *
56new_py_cvec(uint_t length) {
57  Py_cvec* vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
58  npy_intp dims[] = { length / 2 + 1, 1 };
59  vec->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
60  vec->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
61  vec->length = length / 2 + 1;
62  return (PyObject*)vec;
63}
64
[92a8800]65int
66PyAubio_PyCvecToCCvec (PyObject *input, cvec_t *i) {
67  if (PyObject_TypeCheck (input, &Py_cvecType)) {
68      Py_cvec * in = (Py_cvec *)input;
69      i->norm = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->norm), 0);
70      i->phas = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)(in->phas), 0);
71      i->length = ((Py_cvec*)input)->length;
72      return 1;
73  } else {
74      PyErr_SetString (PyExc_ValueError, "input array should be aubio.cvec");
75      return 0;
76  }
77}
78
[f826349]79static PyObject *
80Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
81{
[7a7b00f]82  int length= 0;
[f826349]83  Py_cvec *self;
[7a7b00f]84  static char *kwlist[] = { "length", NULL };
[f826349]85
[7a7b00f]86  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
87          &length)) {
[f826349]88    return NULL;
89  }
90
91  self = (Py_cvec *) type->tp_alloc (type, 0);
92
[eb93592]93  self->length = Py_default_vector_length / 2 + 1;
[f826349]94
95  if (self == NULL) {
96    return NULL;
97  }
98
99  if (length > 0) {
[eb93592]100    self->length = length / 2 + 1;
[f826349]101  } else if (length < 0) {
102    PyErr_SetString (PyExc_ValueError,
103        "can not use negative number of elements");
104    return NULL;
105  }
106
107  return (PyObject *) self;
108}
109
110static int
111Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
112{
[ede5d38]113  npy_intp dims[] = { self->length, 1 };
114  self->phas = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
115  self->norm = PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
[f826349]116  return 0;
117}
118
119static void
120Py_cvec_del (Py_cvec * self)
121{
[ede5d38]122  Py_DECREF(self->norm);
123  Py_DECREF(self->phas);
[770b9e7]124  Py_TYPE(self)->tp_free ((PyObject *) self);
[f826349]125}
126
127static PyObject *
128Py_cvec_repr (Py_cvec * self, PyObject * unused)
129{
130  PyObject *format = NULL;
131  PyObject *args = NULL;
132  PyObject *result = NULL;
133
[5c1200a]134  format = PyUnicode_FromString ("aubio cvec of %d elements");
[f826349]135  if (format == NULL) {
136    goto fail;
137  }
138
[754a987]139  args = PyLong_FromLong(self->length);
[f826349]140  if (args == NULL) {
141    goto fail;
142  }
[92a8800]143  // hide actual norm / phas content
[f826349]144
[5c1200a]145  result = PyUnicode_Format (format, args);
[f826349]146
147fail:
148  Py_XDECREF (format);
149  Py_XDECREF (args);
150
151  return result;
152}
153
[615ac7d]154PyObject *
155Py_cvec_get_norm (Py_cvec * self, void *closure)
156{
[ede5d38]157  // we want self->norm to still exist after our caller return it
[92a8800]158  Py_INCREF(self->norm);
159  return (PyObject*)(self->norm);
[615ac7d]160}
161
162PyObject *
163Py_cvec_get_phas (Py_cvec * self, void *closure)
164{
[ede5d38]165  // we want self->phas to still exist after our caller return it
[92a8800]166  Py_INCREF(self->phas);
167  return (PyObject *)(self->phas);
[615ac7d]168}
169
170static int
[a8aaef3]171Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
[615ac7d]172{
[a138975]173  npy_intp length;
[34d0c25]174  if (!PyAubio_IsValidVector(input)) {
[4deb255]175    return -1;
[a8aaef3]176  }
[a138975]177  length = PyArray_SIZE ((PyArrayObject *)input);
[34d0c25]178  if (length != vec->length) {
179    PyErr_Format (PyExc_ValueError,
[a203d0e]180        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
[34d0c25]181        vec->length);
[4deb255]182    return -1;
[a8aaef3]183  }
184
[34d0c25]185  Py_XDECREF(vec->norm);
186  vec->norm = input;
187  Py_INCREF(vec->norm);
[615ac7d]188  return 0;
189}
190
191static int
[a8aaef3]192Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
[615ac7d]193{
[a138975]194  npy_intp length;
[34d0c25]195  if (!PyAubio_IsValidVector(input)) {
[4deb255]196    return -1;
[a8aaef3]197  }
[a138975]198  length = PyArray_SIZE ((PyArrayObject *)input);
[34d0c25]199  if (length != vec->length) {
200    PyErr_Format (PyExc_ValueError,
[a203d0e]201        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
[34d0c25]202        vec->length);
[4deb255]203    return -1;
[a8aaef3]204  }
205
[34d0c25]206  Py_XDECREF(vec->phas);
207  vec->phas = input;
208  Py_INCREF(vec->phas);
[615ac7d]209  return 0;
210}
211
[f826349]212static PyMemberDef Py_cvec_members[] = {
213  // TODO remove READONLY flag and define getter/setter
214  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
[92948ab]215      "int: Length of `norm` and `phas` vectors."},
[f826349]216  {NULL}                        /* Sentinel */
217};
218
219static PyMethodDef Py_cvec_methods[] = {
220  {NULL}
221};
222
[615ac7d]223static PyGetSetDef Py_cvec_getseters[] = {
[92948ab]224  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
225      "numpy.ndarray: Vector of shape `(length,)` containing the magnitude.",
[615ac7d]226      NULL},
[92948ab]227  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
228      "numpy.ndarray: Vector of shape `(length,)` containing the phase.",
[615ac7d]229      NULL},
230  {NULL} /* sentinel */
231};
232
[f826349]233PyTypeObject Py_cvecType = {
[5c1200a]234  PyVarObject_HEAD_INIT(NULL, 0)
[f826349]235  "aubio.cvec",                 /* tp_name           */
236  sizeof (Py_cvec),             /* tp_basicsize      */
237  0,                            /* tp_itemsize       */
238  (destructor) Py_cvec_del,     /* tp_dealloc        */
239  0,                            /* tp_print          */
240  0,                            /* tp_getattr        */
241  0,                            /* tp_setattr        */
242  0,                            /* tp_compare        */
243  (reprfunc) Py_cvec_repr,      /* tp_repr           */
244  0,                            /* tp_as_number      */
[f2ce0fc]245  0, //&Py_cvec_tp_as_sequence, /* tp_as_sequence    */
[f826349]246  0,                            /* tp_as_mapping     */
247  0,                            /* tp_hash           */
248  0,                            /* tp_call           */
249  0,                            /* tp_str            */
250  0,                            /* tp_getattro       */
251  0,                            /* tp_setattro       */
252  0,                            /* tp_as_buffer      */
253  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
254  Py_cvec_doc,                  /* tp_doc            */
255  0,                            /* tp_traverse       */
256  0,                            /* tp_clear          */
257  0,                            /* tp_richcompare    */
258  0,                            /* tp_weaklistoffset */
259  0,                            /* tp_iter           */
260  0,                            /* tp_iternext       */
261  Py_cvec_methods,              /* tp_methods        */
262  Py_cvec_members,              /* tp_members        */
[615ac7d]263  Py_cvec_getseters,            /* tp_getset         */
[f826349]264  0,                            /* tp_base           */
265  0,                            /* tp_dict           */
266  0,                            /* tp_descr_get      */
267  0,                            /* tp_descr_set      */
268  0,                            /* tp_dictoffset     */
269  (initproc) Py_cvec_init,      /* tp_init           */
270  0,                            /* tp_alloc          */
271  Py_cvec_new,                  /* tp_new            */
[0e70ef9]272  0,
273  0,
274  0,
275  0,
276  0,
277  0,
278  0,
279  0,
280  0,
[f826349]281};
Note: See TracBrowser for help on using the repository browser.