python/ext: simplify memory allocations, removed unneeded malloc/free calls
[aubio.git] / python / ext / aubiomodule.c
1 #define PY_AUBIO_MODULE_MAIN
2 #include "aubio-types.h"
3 #include "aubio-generated.h"
4 #include "py-musicutils.h"
5
6 static char aubio_module_doc[] = "Python module for the aubio library";
7
8 static char Py_alpha_norm_doc[] = ""
9 "alpha_norm(fvec, integer) -> float\n"
10 "\n"
11 "Compute alpha normalisation factor on vector, given alpha\n"
12 "\n"
13 "Example\n"
14 "-------\n"
15 "\n"
16 ">>> b = alpha_norm(a, 9)";
17
18 static char Py_bintomidi_doc[] = ""
19 "bintomidi(float, samplerate = integer, fftsize = integer) -> float\n"
20 "\n"
21 "Convert bin (float) to midi (float), given the sampling rate and the FFT size\n"
22 "\n"
23 "Example\n"
24 "-------\n"
25 "\n"
26 ">>> midi = bintomidi(float, samplerate = 44100, fftsize = 1024)";
27
28 static char Py_miditobin_doc[] = ""
29 "miditobin(float, samplerate = integer, fftsize = integer) -> float\n"
30 "\n"
31 "Convert midi (float) to bin (float), given the sampling rate and the FFT size\n"
32 "\n"
33 "Example\n"
34 "-------\n"
35 "\n"
36 ">>> bin = miditobin(midi, samplerate = 44100, fftsize = 1024)";
37
38 static char Py_bintofreq_doc[] = ""
39 "bintofreq(float, samplerate = integer, fftsize = integer) -> float\n"
40 "\n"
41 "Convert bin number (float) in frequency (Hz), given the sampling rate and the FFT size\n"
42 "\n"
43 "Example\n"
44 "-------\n"
45 "\n"
46 ">>> freq = bintofreq(bin, samplerate = 44100, fftsize = 1024)";
47
48 static char Py_freqtobin_doc[] = ""
49 "freqtobin(float, samplerate = integer, fftsize = integer) -> float\n"
50 "\n"
51 "Convert frequency (Hz) in bin number (float), given the sampling rate and the FFT size\n"
52 "\n"
53 "Example\n"
54 "-------\n"
55 "\n"
56 ">>> bin = freqtobin(freq, samplerate = 44100, fftsize = 1024)";
57
58 static char Py_zero_crossing_rate_doc[] = ""
59 "zero_crossing_rate(fvec) -> float\n"
60 "\n"
61 "Compute Zero crossing rate of a vector\n"
62 "\n"
63 "Example\n"
64 "-------\n"
65 "\n"
66 ">>> z = zero_crossing_rate(a)";
67
68 static char Py_min_removal_doc[] = ""
69 "min_removal(fvec) -> float\n"
70 "\n"
71 "Remove the minimum value of a vector, in-place modification\n"
72 "\n"
73 "Example\n"
74 "-------\n"
75 "\n"
76 ">>> min_removal(a)";
77
78 extern void add_generated_objects ( PyObject *m );
79 extern void add_ufuncs ( PyObject *m );
80 extern int generated_types_ready(void);
81
82 static PyObject *
83 Py_alpha_norm (PyObject * self, PyObject * args)
84 {
85   PyObject *input;
86   fvec_t vec;
87   smpl_t alpha;
88   PyObject *result;
89
90   if (!PyArg_ParseTuple (args, "Of:alpha_norm", &input, &alpha)) {
91     return NULL;
92   }
93
94   if (input == NULL) {
95     return NULL;
96   }
97
98   if (!PyAubio_ArrayToCFvec(input, &vec)) {
99     return NULL;
100   }
101
102   // compute the function
103   result = Py_BuildValue ("f", fvec_alpha_norm (&vec, alpha));
104   if (result == NULL) {
105     return NULL;
106   }
107
108   return result;
109 }
110
111 static PyObject *
112 Py_bintomidi (PyObject * self, PyObject * args)
113 {
114   smpl_t input, samplerate, fftsize;
115   smpl_t output;
116
117   if (!PyArg_ParseTuple (args, "|fff", &input, &samplerate, &fftsize)) {
118     return NULL;
119   }
120
121   output = aubio_bintomidi (input, samplerate, fftsize);
122
123   return (PyObject *)PyFloat_FromDouble (output);
124 }
125
126 static PyObject *
127 Py_miditobin (PyObject * self, PyObject * args)
128 {
129   smpl_t input, samplerate, fftsize;
130   smpl_t output;
131
132   if (!PyArg_ParseTuple (args, "|fff", &input, &samplerate, &fftsize)) {
133     return NULL;
134   }
135
136   output = aubio_miditobin (input, samplerate, fftsize);
137
138   return (PyObject *)PyFloat_FromDouble (output);
139 }
140
141 static PyObject *
142 Py_bintofreq (PyObject * self, PyObject * args)
143 {
144   smpl_t input, samplerate, fftsize;
145   smpl_t output;
146
147   if (!PyArg_ParseTuple (args, "|fff", &input, &samplerate, &fftsize)) {
148     return NULL;
149   }
150
151   output = aubio_bintofreq (input, samplerate, fftsize);
152
153   return (PyObject *)PyFloat_FromDouble (output);
154 }
155
156 static PyObject *
157 Py_freqtobin (PyObject * self, PyObject * args)
158 {
159   smpl_t input, samplerate, fftsize;
160   smpl_t output;
161
162   if (!PyArg_ParseTuple (args, "|fff", &input, &samplerate, &fftsize)) {
163     return NULL;
164   }
165
166   output = aubio_freqtobin (input, samplerate, fftsize);
167
168   return (PyObject *)PyFloat_FromDouble (output);
169 }
170
171 static PyObject *
172 Py_zero_crossing_rate (PyObject * self, PyObject * args)
173 {
174   PyObject *input;
175   fvec_t vec;
176   PyObject *result;
177
178   if (!PyArg_ParseTuple (args, "O:zero_crossing_rate", &input)) {
179     return NULL;
180   }
181
182   if (input == NULL) {
183     return NULL;
184   }
185
186   if (!PyAubio_ArrayToCFvec(input, &vec)) {
187     return NULL;
188   }
189
190   // compute the function
191   result = Py_BuildValue ("f", aubio_zero_crossing_rate (&vec));
192   if (result == NULL) {
193     return NULL;
194   }
195
196   return result;
197 }
198
199 static PyObject *
200 Py_min_removal(PyObject * self, PyObject * args)
201 {
202   PyObject *input;
203   fvec_t vec;
204
205   if (!PyArg_ParseTuple (args, "O:min_removal", &input)) {
206     return NULL;
207   }
208
209   if (input == NULL) {
210     return NULL;
211   }
212
213   if (!PyAubio_ArrayToCFvec(input, &vec)) {
214     return NULL;
215   }
216
217   // compute the function
218   fvec_min_removal (&vec);
219
220   // since this function does not return, we could return None
221   //Py_RETURN_NONE;
222   // however it is convenient to return the modified vector
223   return (PyObject *) PyAubio_CFvecToArray(&vec);
224   // or even without converting it back to an array
225   //Py_INCREF(vec);
226   //return (PyObject *)vec;
227 }
228
229 static PyMethodDef aubio_methods[] = {
230   {"bintomidi", Py_bintomidi, METH_VARARGS, Py_bintomidi_doc},
231   {"miditobin", Py_miditobin, METH_VARARGS, Py_miditobin_doc},
232   {"bintofreq", Py_bintofreq, METH_VARARGS, Py_bintofreq_doc},
233   {"freqtobin", Py_freqtobin, METH_VARARGS, Py_freqtobin_doc},
234   {"alpha_norm", Py_alpha_norm, METH_VARARGS, Py_alpha_norm_doc},
235   {"zero_crossing_rate", Py_zero_crossing_rate, METH_VARARGS, Py_zero_crossing_rate_doc},
236   {"min_removal", Py_min_removal, METH_VARARGS, Py_min_removal_doc},
237   {"level_lin", Py_aubio_level_lin, METH_VARARGS, Py_aubio_level_lin_doc},
238   {"db_spl", Py_aubio_db_spl, METH_VARARGS, Py_aubio_db_spl_doc},
239   {"silence_detection", Py_aubio_silence_detection, METH_VARARGS, Py_aubio_silence_detection_doc},
240   {"level_detection", Py_aubio_level_detection, METH_VARARGS, Py_aubio_level_detection_doc},
241   {"window", Py_aubio_window, METH_VARARGS, Py_aubio_window_doc},
242   {NULL, NULL} /* Sentinel */
243 };
244
245 #if PY_MAJOR_VERSION >= 3
246 // Python3 module definition
247 static struct PyModuleDef moduledef = {
248    PyModuleDef_HEAD_INIT,
249    "_aubio",          /* m_name */
250    aubio_module_doc,  /* m_doc */
251    -1,                /* m_size */
252    aubio_methods,     /* m_methods */
253    NULL,              /* m_reload */
254    NULL,              /* m_traverse */
255    NULL,              /* m_clear */
256    NULL,              /* m_free */
257 };
258 #endif
259
260 static PyObject *
261 initaubio (void)
262 {
263   PyObject *m = NULL;
264   int err;
265
266   // fvec is defined in __init__.py
267   if (   (PyType_Ready (&Py_cvecType) < 0)
268       || (PyType_Ready (&Py_filterType) < 0)
269       || (PyType_Ready (&Py_filterbankType) < 0)
270       || (PyType_Ready (&Py_fftType) < 0)
271       || (PyType_Ready (&Py_pvocType) < 0)
272       || (PyType_Ready (&Py_sourceType) < 0)
273       || (PyType_Ready (&Py_sinkType) < 0)
274       // generated objects
275       || (generated_types_ready() < 0 )
276   ) {
277     return m;
278   }
279
280 #if PY_MAJOR_VERSION >= 3
281   m = PyModule_Create(&moduledef);
282 #else
283   m = Py_InitModule3 ("_aubio", aubio_methods, aubio_module_doc);
284 #endif
285
286   if (m == NULL) {
287     return m;
288   }
289
290   err = _import_array ();
291   if (err != 0) {
292     fprintf (stderr,
293         "Unable to import Numpy array from aubio module (error %d)\n", err);
294   }
295
296   Py_INCREF (&Py_cvecType);
297   PyModule_AddObject (m, "cvec", (PyObject *) & Py_cvecType);
298   Py_INCREF (&Py_filterType);
299   PyModule_AddObject (m, "digital_filter", (PyObject *) & Py_filterType);
300   Py_INCREF (&Py_filterbankType);
301   PyModule_AddObject (m, "filterbank", (PyObject *) & Py_filterbankType);
302   Py_INCREF (&Py_fftType);
303   PyModule_AddObject (m, "fft", (PyObject *) & Py_fftType);
304   Py_INCREF (&Py_pvocType);
305   PyModule_AddObject (m, "pvoc", (PyObject *) & Py_pvocType);
306   Py_INCREF (&Py_sourceType);
307   PyModule_AddObject (m, "source", (PyObject *) & Py_sourceType);
308   Py_INCREF (&Py_sinkType);
309   PyModule_AddObject (m, "sink", (PyObject *) & Py_sinkType);
310
311   // add generated objects
312   add_generated_objects(m);
313
314   // add ufunc
315   add_ufuncs(m);
316
317   return m;
318 }
319
320 #if PY_MAJOR_VERSION >= 3
321     // Python3 init
322     PyMODINIT_FUNC PyInit__aubio(void)
323     {
324         return initaubio();
325     }
326 #else
327     // Python 2 init
328     PyMODINIT_FUNC init_aubio(void)
329     {
330         initaubio();
331     }
332 #endif