source: python/ext/py-cvec.c @ 9b05ea9

feature/crepe
Last change on this file since 9b05ea9 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
Line 
1#include "aubio-types.h"
2
3/* cvec type definition
4
5class cvec():
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)
10
11*/
12
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
22static char Py_cvec_doc[] = ""
23"cvec(size)\n"
24"\n"
25"A container holding spectral data.\n"
26"\n"
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"
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"
51"fvec, fft, pvoc\n"
52"";
53
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
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
79static PyObject *
80Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
81{
82  int length= 0;
83  Py_cvec *self;
84  static char *kwlist[] = { "length", NULL };
85
86  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
87          &length)) {
88    return NULL;
89  }
90
91  self = (Py_cvec *) type->tp_alloc (type, 0);
92
93  self->length = Py_default_vector_length / 2 + 1;
94
95  if (self == NULL) {
96    return NULL;
97  }
98
99  if (length > 0) {
100    self->length = length / 2 + 1;
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{
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);
116  return 0;
117}
118
119static void
120Py_cvec_del (Py_cvec * self)
121{
122  Py_DECREF(self->norm);
123  Py_DECREF(self->phas);
124  Py_TYPE(self)->tp_free ((PyObject *) self);
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
134  format = PyUnicode_FromString ("aubio cvec of %d elements");
135  if (format == NULL) {
136    goto fail;
137  }
138
139  args = PyLong_FromLong(self->length);
140  if (args == NULL) {
141    goto fail;
142  }
143  // hide actual norm / phas content
144
145  result = PyUnicode_Format (format, args);
146
147fail:
148  Py_XDECREF (format);
149  Py_XDECREF (args);
150
151  return result;
152}
153
154PyObject *
155Py_cvec_get_norm (Py_cvec * self, void *closure)
156{
157  // we want self->norm to still exist after our caller return it
158  Py_INCREF(self->norm);
159  return (PyObject*)(self->norm);
160}
161
162PyObject *
163Py_cvec_get_phas (Py_cvec * self, void *closure)
164{
165  // we want self->phas to still exist after our caller return it
166  Py_INCREF(self->phas);
167  return (PyObject *)(self->phas);
168}
169
170static int
171Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
172{
173  npy_intp length;
174  if (!PyAubio_IsValidVector(input)) {
175    return -1;
176  }
177  length = PyArray_SIZE ((PyArrayObject *)input);
178  if (length != vec->length) {
179    PyErr_Format (PyExc_ValueError,
180        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
181        vec->length);
182    return -1;
183  }
184
185  Py_XDECREF(vec->norm);
186  vec->norm = input;
187  Py_INCREF(vec->norm);
188  return 0;
189}
190
191static int
192Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
193{
194  npy_intp length;
195  if (!PyAubio_IsValidVector(input)) {
196    return -1;
197  }
198  length = PyArray_SIZE ((PyArrayObject *)input);
199  if (length != vec->length) {
200    PyErr_Format (PyExc_ValueError,
201        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
202        vec->length);
203    return -1;
204  }
205
206  Py_XDECREF(vec->phas);
207  vec->phas = input;
208  Py_INCREF(vec->phas);
209  return 0;
210}
211
212static PyMemberDef Py_cvec_members[] = {
213  // TODO remove READONLY flag and define getter/setter
214  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
215      "int: Length of `norm` and `phas` vectors."},
216  {NULL}                        /* Sentinel */
217};
218
219static PyMethodDef Py_cvec_methods[] = {
220  {NULL}
221};
222
223static PyGetSetDef Py_cvec_getseters[] = {
224  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
225      "numpy.ndarray: Vector of shape `(length,)` containing the magnitude.",
226      NULL},
227  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
228      "numpy.ndarray: Vector of shape `(length,)` containing the phase.",
229      NULL},
230  {NULL} /* sentinel */
231};
232
233PyTypeObject Py_cvecType = {
234  PyVarObject_HEAD_INIT(NULL, 0)
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      */
245  0, //&Py_cvec_tp_as_sequence, /* tp_as_sequence    */
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        */
263  Py_cvec_getseters,            /* tp_getset         */
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            */
272  0,
273  0,
274  0,
275  0,
276  0,
277  0,
278  0,
279  0,
280  0,
281};
Note: See TracBrowser for help on using the repository browser.