source: python/ext/aubiomodule.c @ e8aed04c

Last change on this file since e8aed04c was df66c37, checked in by Paul Brossier <piem@piem.org>, 6 years ago

[py] alpha_norm and zero_crossing_rate use PyFloat_FromDouble

  • Property mode set to 100644
File size: 11.6 KB
Line 
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
10static char aubio_module_doc[] = "Python module for the aubio library";
11
12static 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
45static 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
72static 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
101static 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
128static 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
155static 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
178static 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
202extern void add_ufuncs ( PyObject *m );
203extern int generated_types_ready(void);
204
205static PyObject *
206Py_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 = PyFloat_FromDouble(fvec_alpha_norm (&vec, alpha));
227  if (result == NULL) {
228    return NULL;
229  }
230
231  return result;
232}
233
234static PyObject *
235Py_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
251static PyObject *
252Py_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
268static PyObject *
269Py_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
285static PyObject *
286Py_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
302static PyObject *
303Py_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 = PyFloat_FromDouble(aubio_zero_crossing_rate (&vec));
323  if (result == NULL) {
324    return NULL;
325  }
326
327  return result;
328}
329
330static PyObject *
331Py_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
360static 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
384static 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
397void
398aubio_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
413static PyObject *
414initaubio (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
Note: See TracBrowser for help on using the repository browser.