[py] add meltohz and hztomel with minimal doc
[aubio.git] / python / ext / aubiomodule.c
1 #define PY_AUBIO_MODULE_MAIN
2 #include "aubio-types.h"
3 #include "py-musicutils.h"
4
5 // this dummy macro is used to convince windows that a string passed as -D flag
6 // is just that, a string, and not a double.
7 #define REDEFINESTRING(x) #x
8 #define DEFINEDSTRING(x) REDEFINESTRING(x)
9
10 static char aubio_module_doc[] = "Python module for the aubio library";
11
12 static char Py_alpha_norm_doc[] = ""
13 "alpha_norm(vec, alpha)\n"
14 "\n"
15 "Compute `alpha` normalisation factor of vector `vec`.\n"
16 "\n"
17 "Parameters\n"
18 "----------\n"
19 "vec : fvec\n"
20 "   input vector\n"
21 "alpha : float\n"
22 "   norm factor\n"
23 "\n"
24 "Returns\n"
25 "-------\n"
26 "float\n"
27 "   p-norm of the input vector, where `p=alpha`\n"
28 "\n"
29 "Example\n"
30 "-------\n"
31 "\n"
32 ">>> a = aubio.fvec(np.arange(10)); alpha = 2\n"
33 ">>> aubio.alpha_norm(a, alpha), (sum(a**alpha)/len(a))**(1./alpha)\n"
34 "(5.338539123535156, 5.338539126015656)\n"
35 "\n"
36 "Note\n"
37 "----\n"
38 "Computed as:\n"
39 "\n"
40 ".. math::\n"
41 "  l_{\\alpha} = \n"
42 "       \\|\\frac{\\sum_{n=0}^{N-1}{{x_n}^{\\alpha}}}{N}\\|^{1/\\alpha}\n"
43 "";
44
45 static char Py_bintomidi_doc[] = ""
46 "bintomidi(fftbin, samplerate, fftsize)\n"
47 "\n"
48 "Convert FFT bin to frequency in midi note, given the sampling rate\n"
49 "and the size of the FFT.\n"
50 "\n"
51 "Parameters\n"
52 "----------\n"
53 "fftbin : float\n"
54 "   input frequency bin\n"
55 "samplerate : float\n"
56 "   sampling rate of the signal\n"
57 "fftsize : float\n"
58 "   size of the FFT\n"
59 "\n"
60 "Returns\n"
61 "-------\n"
62 "float\n"
63 "   Frequency converted to midi note.\n"
64 "\n"
65 "Example\n"
66 "-------\n"
67 "\n"
68 ">>> aubio.bintomidi(10, 44100, 1024)\n"
69 "68.62871551513672\n"
70 "";
71
72 static char Py_miditobin_doc[] = ""
73 "miditobin(midi, samplerate, fftsize)\n"
74 "\n"
75 "Convert frequency in midi note to FFT bin, given the sampling rate\n"
76 "and the size of the FFT.\n"
77 "\n"
78 "Parameters\n"
79 "----------\n"
80 "midi : float\n"
81 "   input frequency, in midi note\n"
82 "samplerate : float\n"
83 "   sampling rate of the signal\n"
84 "fftsize : float\n"
85 "   size of the FFT\n"
86 "\n"
87 "Returns\n"
88 "-------\n"
89 "float\n"
90 "   Frequency converted to FFT bin.\n"
91 "\n"
92 "Examples\n"
93 "--------\n"
94 "\n"
95 ">>> aubio.miditobin(69, 44100, 1024)\n"
96 "10.216779708862305\n"
97 ">>> aubio.miditobin(75.08, 32000, 512)\n"
98 "10.002175331115723\n"
99 "";
100
101 static char Py_bintofreq_doc[] = ""
102 "bintofreq(fftbin, samplerate, fftsize)\n"
103 "\n"
104 "Convert FFT bin to frequency in Hz, given the sampling rate\n"
105 "and the size of the FFT.\n"
106 "\n"
107 "Parameters\n"
108 "----------\n"
109 "fftbin : float\n"
110 "   input frequency bin\n"
111 "samplerate : float\n"
112 "   sampling rate of the signal\n"
113 "fftsize : float\n"
114 "   size of the FFT\n"
115 "\n"
116 "Returns\n"
117 "-------\n"
118 "float\n"
119 "   Frequency converted to Hz.\n"
120 "\n"
121 "Example\n"
122 "-------\n"
123 "\n"
124 ">>> aubio.bintofreq(10, 44100, 1024)\n"
125 "430.6640625\n"
126 "";
127
128 static char Py_freqtobin_doc[] = ""
129 "freqtobin(freq, samplerate, fftsize)\n"
130 "\n"
131 "Convert frequency in Hz to FFT bin, given the sampling rate\n"
132 "and the size of the FFT.\n"
133 "\n"
134 "Parameters\n"
135 "----------\n"
136 "midi : float\n"
137 "   input frequency, in midi note\n"
138 "samplerate : float\n"
139 "   sampling rate of the signal\n"
140 "fftsize : float\n"
141 "   size of the FFT\n"
142 "\n"
143 "Returns\n"
144 "-------\n"
145 "float\n"
146 "   Frequency converted to FFT bin.\n"
147 "\n"
148 "Examples\n"
149 "--------\n"
150 "\n"
151 ">>> aubio.freqtobin(440, 44100, 1024)\n"
152 "10.216779708862305\n"
153 "";
154
155 static char Py_zero_crossing_rate_doc[] = ""
156 "zero_crossing_rate(vec)\n"
157 "\n"
158 "Compute zero-crossing rate of `vec`.\n"
159 "\n"
160 "Parameters\n"
161 "----------\n"
162 "vec : fvec\n"
163 "   input vector\n"
164 "\n"
165 "Returns\n"
166 "-------\n"
167 "float\n"
168 "   Zero-crossing rate.\n"
169 "\n"
170 "Example\n"
171 "-------\n"
172 "\n"
173 ">>> a = np.linspace(-1., 1., 1000, dtype=aubio.float_type)\n"
174 ">>> aubio.zero_crossing_rate(a), 1/1000\n"
175 "(0.0010000000474974513, 0.001)\n"
176 "";
177
178 static char Py_min_removal_doc[] = ""
179 "min_removal(vec)\n"
180 "\n"
181 "Remove the minimum value of a vector to each of its element.\n"
182 "\n"
183 "Modifies the input vector in-place and returns a reference to it.\n"
184 "\n"
185 "Parameters\n"
186 "----------\n"
187 "vec : fvec\n"
188 "   input vector\n"
189 "\n"
190 "Returns\n"
191 "-------\n"
192 "fvec\n"
193 "   modified input vector\n"
194 "\n"
195 "Example\n"
196 "-------\n"
197 "\n"
198 ">>> aubio.min_removal(aubio.fvec(np.arange(1,4)))\n"
199 "array([0., 1., 2.], dtype=" AUBIO_NPY_SMPL_STR ")\n"
200 "";
201
202 extern void add_ufuncs ( PyObject *m );
203 extern int generated_types_ready(void);
204
205 static PyObject *
206 Py_alpha_norm (PyObject * self, PyObject * args)
207 {
208   PyObject *input;
209   fvec_t vec;
210   smpl_t alpha;
211   PyObject *result;
212
213   if (!PyArg_ParseTuple (args, "O" AUBIO_NPY_SMPL_CHR ":alpha_norm", &input, &alpha)) {
214     return NULL;
215   }
216
217   if (input == NULL) {
218     return NULL;
219   }
220
221   if (!PyAubio_ArrayToCFvec(input, &vec)) {
222     return NULL;
223   }
224
225   // compute the function
226   result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, fvec_alpha_norm (&vec, alpha));
227   if (result == NULL) {
228     return NULL;
229   }
230
231   return result;
232 }
233
234 static PyObject *
235 Py_bintomidi (PyObject * self, PyObject * args)
236 {
237   smpl_t input, samplerate, fftsize;
238   smpl_t output;
239
240   if (!PyArg_ParseTuple (args,
241         "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
242         &input, &samplerate, &fftsize)) {
243     return NULL;
244   }
245
246   output = aubio_bintomidi (input, samplerate, fftsize);
247
248   return (PyObject *)PyFloat_FromDouble (output);
249 }
250
251 static PyObject *
252 Py_miditobin (PyObject * self, PyObject * args)
253 {
254   smpl_t input, samplerate, fftsize;
255   smpl_t output;
256
257   if (!PyArg_ParseTuple (args,
258         "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
259         &input, &samplerate, &fftsize)) {
260     return NULL;
261   }
262
263   output = aubio_miditobin (input, samplerate, fftsize);
264
265   return (PyObject *)PyFloat_FromDouble (output);
266 }
267
268 static PyObject *
269 Py_bintofreq (PyObject * self, PyObject * args)
270 {
271   smpl_t input, samplerate, fftsize;
272   smpl_t output;
273
274   if (!PyArg_ParseTuple (args,
275         "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
276         &input, &samplerate, &fftsize)) {
277     return NULL;
278   }
279
280   output = aubio_bintofreq (input, samplerate, fftsize);
281
282   return (PyObject *)PyFloat_FromDouble (output);
283 }
284
285 static PyObject *
286 Py_freqtobin (PyObject * self, PyObject * args)
287 {
288   smpl_t input, samplerate, fftsize;
289   smpl_t output;
290
291   if (!PyArg_ParseTuple (args,
292         "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
293         &input, &samplerate, &fftsize)) {
294     return NULL;
295   }
296
297   output = aubio_freqtobin (input, samplerate, fftsize);
298
299   return (PyObject *)PyFloat_FromDouble (output);
300 }
301
302 static PyObject *
303 Py_zero_crossing_rate (PyObject * self, PyObject * args)
304 {
305   PyObject *input;
306   fvec_t vec;
307   PyObject *result;
308
309   if (!PyArg_ParseTuple (args, "O:zero_crossing_rate", &input)) {
310     return NULL;
311   }
312
313   if (input == NULL) {
314     return NULL;
315   }
316
317   if (!PyAubio_ArrayToCFvec(input, &vec)) {
318     return NULL;
319   }
320
321   // compute the function
322   result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, aubio_zero_crossing_rate (&vec));
323   if (result == NULL) {
324     return NULL;
325   }
326
327   return result;
328 }
329
330 static PyObject *
331 Py_min_removal(PyObject * self, PyObject * args)
332 {
333   PyObject *input;
334   fvec_t vec;
335
336   if (!PyArg_ParseTuple (args, "O:min_removal", &input)) {
337     return NULL;
338   }
339
340   if (input == NULL) {
341     return NULL;
342   }
343
344   if (!PyAubio_ArrayToCFvec(input, &vec)) {
345     return NULL;
346   }
347
348   // compute the function
349   fvec_min_removal (&vec);
350
351   // since this function does not return, we could return None
352   //Py_RETURN_NONE;
353   // however it is convenient to return the modified vector
354   return (PyObject *) PyAubio_CFvecToArray(&vec);
355   // or even without converting it back to an array
356   //Py_INCREF(vec);
357   //return (PyObject *)vec;
358 }
359
360 static PyMethodDef aubio_methods[] = {
361   {"bintomidi", Py_bintomidi, METH_VARARGS, Py_bintomidi_doc},
362   {"miditobin", Py_miditobin, METH_VARARGS, Py_miditobin_doc},
363   {"bintofreq", Py_bintofreq, METH_VARARGS, Py_bintofreq_doc},
364   {"freqtobin", Py_freqtobin, METH_VARARGS, Py_freqtobin_doc},
365   {"alpha_norm", Py_alpha_norm, METH_VARARGS, Py_alpha_norm_doc},
366   {"zero_crossing_rate", Py_zero_crossing_rate, METH_VARARGS, Py_zero_crossing_rate_doc},
367   {"min_removal", Py_min_removal, METH_VARARGS, Py_min_removal_doc},
368   {"level_lin", Py_aubio_level_lin, METH_VARARGS, Py_aubio_level_lin_doc},
369   {"db_spl", Py_aubio_db_spl, METH_VARARGS, Py_aubio_db_spl_doc},
370   {"silence_detection", Py_aubio_silence_detection, METH_VARARGS, Py_aubio_silence_detection_doc},
371   {"level_detection", Py_aubio_level_detection, METH_VARARGS, Py_aubio_level_detection_doc},
372   {"window", Py_aubio_window, METH_VARARGS, Py_aubio_window_doc},
373   {"shift", Py_aubio_shift, METH_VARARGS, Py_aubio_shift_doc},
374   {"ishift", Py_aubio_ishift, METH_VARARGS, Py_aubio_ishift_doc},
375   {"hztomel", Py_aubio_hztomel, METH_VARARGS|METH_KEYWORDS, Py_aubio_hztomel_doc},
376   {"meltohz", Py_aubio_meltohz, METH_VARARGS|METH_KEYWORDS, Py_aubio_meltohz_doc},
377   {"hztomel_htk", Py_aubio_hztomel_htk, METH_VARARGS, Py_aubio_hztomel_htk_doc},
378   {"meltohz_htk", Py_aubio_meltohz_htk, METH_VARARGS, Py_aubio_meltohz_htk_doc},
379   {NULL, NULL, 0, NULL} /* Sentinel */
380 };
381
382 #if PY_MAJOR_VERSION >= 3
383 // Python3 module definition
384 static struct PyModuleDef moduledef = {
385    PyModuleDef_HEAD_INIT,
386    "_aubio",          /* m_name */
387    aubio_module_doc,  /* m_doc */
388    -1,                /* m_size */
389    aubio_methods,     /* m_methods */
390    NULL,              /* m_reload */
391    NULL,              /* m_traverse */
392    NULL,              /* m_clear */
393    NULL,              /* m_free */
394 };
395 #endif
396
397 void
398 aubio_log_function(int level, const char *message, void *data)
399 {
400   // remove trailing \n
401   char *pos;
402   if ((pos=strchr(message, '\n')) != NULL) {
403         *pos = '\0';
404   }
405   // warning or error
406   if (level == AUBIO_LOG_ERR) {
407     PyErr_Format(PyExc_RuntimeError, "%s", message);
408   } else {
409     PyErr_WarnEx(PyExc_UserWarning, message, 1);
410   }
411 }
412
413 static PyObject *
414 initaubio (void)
415 {
416   PyObject *m = NULL;
417   int err;
418
419   // fvec is defined in __init__.py
420   if (   (PyType_Ready (&Py_cvecType) < 0)
421       || (PyType_Ready (&Py_filterType) < 0)
422       || (PyType_Ready (&Py_filterbankType) < 0)
423       || (PyType_Ready (&Py_fftType) < 0)
424       || (PyType_Ready (&Py_pvocType) < 0)
425       || (PyType_Ready (&Py_sourceType) < 0)
426       || (PyType_Ready (&Py_sinkType) < 0)
427       // generated objects
428       || (generated_types_ready() < 0 )
429   ) {
430     return m;
431   }
432
433 #if PY_MAJOR_VERSION >= 3
434   m = PyModule_Create(&moduledef);
435 #else
436   m = Py_InitModule3 ("_aubio", aubio_methods, aubio_module_doc);
437 #endif
438
439   if (m == NULL) {
440     return m;
441   }
442
443   err = _import_array ();
444   if (err != 0) {
445     fprintf (stderr,
446         "Unable to import Numpy array from aubio module (error %d)\n", err);
447   }
448
449   Py_INCREF (&Py_cvecType);
450   PyModule_AddObject (m, "cvec", (PyObject *) & Py_cvecType);
451   Py_INCREF (&Py_filterType);
452   PyModule_AddObject (m, "digital_filter", (PyObject *) & Py_filterType);
453   Py_INCREF (&Py_filterbankType);
454   PyModule_AddObject (m, "filterbank", (PyObject *) & Py_filterbankType);
455   Py_INCREF (&Py_fftType);
456   PyModule_AddObject (m, "fft", (PyObject *) & Py_fftType);
457   Py_INCREF (&Py_pvocType);
458   PyModule_AddObject (m, "pvoc", (PyObject *) & Py_pvocType);
459   Py_INCREF (&Py_sourceType);
460   PyModule_AddObject (m, "source", (PyObject *) & Py_sourceType);
461   Py_INCREF (&Py_sinkType);
462   PyModule_AddObject (m, "sink", (PyObject *) & Py_sinkType);
463
464   PyModule_AddStringConstant(m, "float_type", AUBIO_NPY_SMPL_STR);
465   PyModule_AddStringConstant(m, "__version__", DEFINEDSTRING(AUBIO_VERSION));
466
467   // add generated objects
468   add_generated_objects(m);
469
470   // add ufunc
471   add_ufuncs(m);
472
473   aubio_log_set_level_function(AUBIO_LOG_ERR, aubio_log_function, NULL);
474   aubio_log_set_level_function(AUBIO_LOG_WRN, aubio_log_function, NULL);
475   return m;
476 }
477
478 #if PY_MAJOR_VERSION >= 3
479     // Python3 init
480     PyMODINIT_FUNC PyInit__aubio(void)
481     {
482         return initaubio();
483     }
484 #else
485     // Python 2 init
486     PyMODINIT_FUNC init_aubio(void)
487     {
488         initaubio();
489     }
490 #endif