8763632780d90784e85582f9a4d5944537a1747b
[aubio.git] / python / ext / py-fft.c
1 #include "aubio-types.h"
2
3 static char Py_fft_doc[] = "fft object";
4
5 typedef struct
6 {
7   PyObject_HEAD
8   aubio_fft_t * o;
9   uint_t win_s;
10   // do / rdo input vectors
11   fvec_t vecin;
12   cvec_t cvecin;
13   // do / rdo output results
14   PyObject *doout;
15   PyObject *rdoout;
16 } Py_fft;
17
18 static PyObject *
19 Py_fft_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
20 {
21   int win_s = 0;
22   Py_fft *self;
23   static char *kwlist[] = { "win_s", NULL };
24
25   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
26           &win_s)) {
27     return NULL;
28   }
29
30   self = (Py_fft *) type->tp_alloc (type, 0);
31
32   if (self == NULL) {
33     return NULL;
34   }
35
36   self->win_s = Py_default_vector_length;
37
38   if (win_s > 0) {
39     self->win_s = win_s;
40   } else if (win_s < 0) {
41     PyErr_SetString (PyExc_ValueError,
42         "can not use negative window size");
43     return NULL;
44   }
45
46   return (PyObject *) self;
47 }
48
49 static int
50 Py_fft_init (Py_fft * self, PyObject * args, PyObject * kwds)
51 {
52   self->o = new_aubio_fft (self->win_s);
53   if (self->o == NULL) {
54     // PyErr_Format(PyExc_RuntimeError, ...) was set above by new_ which called
55     // AUBIO_ERR when failing
56     return -1;
57   }
58
59   self->doout = new_py_cvec(self->win_s);
60   self->rdoout = new_py_fvec(self->win_s);
61
62   return 0;
63 }
64
65 static void
66 Py_fft_del (Py_fft *self, PyObject *unused)
67 {
68   Py_XDECREF(self->doout);
69   Py_XDECREF(self->rdoout);
70   if (self->o) {
71     del_aubio_fft(self->o);
72   }
73   Py_TYPE(self)->tp_free((PyObject *) self);
74 }
75
76 static PyObject *
77 Py_fft_do(Py_fft * self, PyObject * args)
78 {
79   PyObject *input;
80   cvec_t c_out;
81
82   if (!PyArg_ParseTuple (args, "O", &input)) {
83     return NULL;
84   }
85
86   if (!PyAubio_ArrayToCFvec(input, &(self->vecin))) {
87     return NULL;
88   }
89
90   if (self->vecin.length != self->win_s) {
91     PyErr_Format(PyExc_ValueError,
92                  "input array has length %d, but fft expects length %d",
93                  self->vecin.length, self->win_s);
94     return NULL;
95   }
96
97   Py_INCREF(self->doout);
98   if (!PyAubio_PyCvecToCCvec(self->doout, &c_out)) {
99     return NULL;
100   }
101   // compute the function
102   aubio_fft_do (self->o, &(self->vecin), &c_out);
103   return self->doout;
104 }
105
106 static PyMemberDef Py_fft_members[] = {
107   {"win_s", T_INT, offsetof (Py_fft, win_s), READONLY,
108     "size of the window"},
109   {NULL}
110 };
111
112 static PyObject *
113 Py_fft_rdo(Py_fft * self, PyObject * args)
114 {
115   PyObject *input;
116   fvec_t out;
117
118   if (!PyArg_ParseTuple (args, "O", &input)) {
119     return NULL;
120   }
121
122   if (!PyAubio_PyCvecToCCvec (input, &(self->cvecin)) ) {
123     return NULL;
124   }
125
126   if (self->cvecin.length != self->win_s / 2 + 1) {
127     PyErr_Format(PyExc_ValueError,
128                  "input cvec has length %d, but fft expects length %d",
129                  self->cvecin.length, self->win_s / 2 + 1);
130     return NULL;
131   }
132
133   Py_INCREF(self->rdoout);
134   if (!PyAubio_ArrayToCFvec(self->rdoout, &out) ) {
135     return NULL;
136   }
137   // compute the function
138   aubio_fft_rdo (self->o, &(self->cvecin), &out);
139   return self->rdoout;
140 }
141
142 static PyMethodDef Py_fft_methods[] = {
143   {"rdo", (PyCFunction) Py_fft_rdo, METH_VARARGS,
144     "synthesis of spectral grain"},
145   {NULL}
146 };
147
148 PyTypeObject Py_fftType = {
149   PyVarObject_HEAD_INIT (NULL, 0)
150   "aubio.fft",
151   sizeof (Py_fft),
152   0,
153   (destructor) Py_fft_del,
154   0,
155   0,
156   0,
157   0,
158   0,
159   0,
160   0,
161   0,
162   0,
163   (ternaryfunc)Py_fft_do,
164   0,
165   0,
166   0,
167   0,
168   Py_TPFLAGS_DEFAULT,
169   Py_fft_doc,
170   0,
171   0,
172   0,
173   0,
174   0,
175   0,
176   Py_fft_methods,
177   Py_fft_members,
178   0,
179   0,
180   0,
181   0,
182   0,
183   0,
184   (initproc) Py_fft_init,
185   0,
186   Py_fft_new,
187   0,
188   0,
189   0,
190   0,
191   0,
192   0,
193   0,
194   0,
195   0,
196 };