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