source: python/ext/aubiomodule.c

Last change on this file 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
RevLine 
[7a6521d]1#define PY_AUBIO_MODULE_MAIN
[ae6e15c]2#include "aubio-types.h"
[913a7f1]3#include "py-musicutils.h"
[ad5203c]4
[f7e30e8]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.
[a159628]7#define REDEFINESTRING(x) #x
8#define DEFINEDSTRING(x) REDEFINESTRING(x)
[f7e30e8]9
[1ba8e60]10static char aubio_module_doc[] = "Python module for the aubio library";
11
12static char Py_alpha_norm_doc[] = ""
[55b6260]13"alpha_norm(vec, alpha)\n"
[1ba8e60]14"\n"
[55b6260]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"
[1ba8e60]28"\n"
29"Example\n"
30"-------\n"
31"\n"
[55b6260]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"";
[1ba8e60]44
45static char Py_bintomidi_doc[] = ""
[57ce9b2]46"bintomidi(fftbin, samplerate, fftsize)\n"
[1ba8e60]47"\n"
[57ce9b2]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"
[1ba8e60]64"\n"
65"Example\n"
66"-------\n"
67"\n"
[57ce9b2]68">>> aubio.bintomidi(10, 44100, 1024)\n"
69"68.62871551513672\n"
70"";
[1ba8e60]71
72static char Py_miditobin_doc[] = ""
[57ce9b2]73"miditobin(midi, samplerate, fftsize)\n"
[1ba8e60]74"\n"
[57ce9b2]75"Convert frequency in midi note to FFT bin, given the sampling rate\n"
76"and the size of the FFT.\n"
[1ba8e60]77"\n"
[57ce9b2]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"
[1ba8e60]88"-------\n"
[57ce9b2]89"float\n"
90"   Frequency converted to FFT bin.\n"
91"\n"
92"Examples\n"
93"--------\n"
[1ba8e60]94"\n"
[57ce9b2]95">>> aubio.miditobin(69, 44100, 1024)\n"
96"10.216779708862305\n"
97">>> aubio.miditobin(75.08, 32000, 512)\n"
98"10.002175331115723\n"
99"";
[1ba8e60]100
101static char Py_bintofreq_doc[] = ""
[7df8df7]102"bintofreq(fftbin, samplerate, fftsize)\n"
[1ba8e60]103"\n"
[7df8df7]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"
[1ba8e60]120"\n"
121"Example\n"
122"-------\n"
123"\n"
[7df8df7]124">>> aubio.bintofreq(10, 44100, 1024)\n"
125"430.6640625\n"
126"";
[1ba8e60]127
128static char Py_freqtobin_doc[] = ""
[7df8df7]129"freqtobin(freq, samplerate, fftsize)\n"
[1ba8e60]130"\n"
[7df8df7]131"Convert frequency in Hz to FFT bin, given the sampling rate\n"
132"and the size of the FFT.\n"
[1ba8e60]133"\n"
[7df8df7]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"
[1ba8e60]144"-------\n"
[7df8df7]145"float\n"
146"   Frequency converted to FFT bin.\n"
147"\n"
148"Examples\n"
149"--------\n"
[1ba8e60]150"\n"
[7df8df7]151">>> aubio.freqtobin(440, 44100, 1024)\n"
152"10.216779708862305\n"
153"";
[1ba8e60]154
155static char Py_zero_crossing_rate_doc[] = ""
[55b6260]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"
[1ba8e60]164"\n"
[55b6260]165"Returns\n"
166"-------\n"
167"float\n"
168"   Zero-crossing rate.\n"
[1ba8e60]169"\n"
170"Example\n"
171"-------\n"
172"\n"
[55b6260]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"";
[1ba8e60]177
178static char Py_min_removal_doc[] = ""
[55b6260]179"min_removal(vec)\n"
180"\n"
181"Remove the minimum value of a vector to each of its element.\n"
[1ba8e60]182"\n"
[55b6260]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"
[1ba8e60]194"\n"
195"Example\n"
196"-------\n"
197"\n"
[55b6260]198">>> aubio.min_removal(aubio.fvec(np.arange(1,4)))\n"
199"array([0., 1., 2.], dtype=" AUBIO_NPY_SMPL_STR ")\n"
200"";
[1ba8e60]201
[b6230d8]202extern void add_ufuncs ( PyObject *m );
203extern int generated_types_ready(void);
[0a6c211]204
[6b1aafc]205static PyObject *
206Py_alpha_norm (PyObject * self, PyObject * args)
207{
208  PyObject *input;
[569b363]209  fvec_t vec;
[6b1aafc]210  smpl_t alpha;
211  PyObject *result;
212
[c6388f4]213  if (!PyArg_ParseTuple (args, "O" AUBIO_NPY_SMPL_CHR ":alpha_norm", &input, &alpha)) {
[6b1aafc]214    return NULL;
215  }
216
217  if (input == NULL) {
218    return NULL;
219  }
220
[569b363]221  if (!PyAubio_ArrayToCFvec(input, &vec)) {
[6b1aafc]222    return NULL;
223  }
224
[ae6e15c]225  // compute the function
[df66c37]226  result = PyFloat_FromDouble(fvec_alpha_norm (&vec, alpha));
[0a6c211]227  if (result == NULL) {
228    return NULL;
229  }
230
231  return result;
232}
233
[6a50b9e]234static PyObject *
235Py_bintomidi (PyObject * self, PyObject * args)
236{
237  smpl_t input, samplerate, fftsize;
238  smpl_t output;
239
[72d08ae]240  if (!PyArg_ParseTuple (args,
241        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
242        &input, &samplerate, &fftsize)) {
[6a50b9e]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
[72d08ae]257  if (!PyArg_ParseTuple (args,
258        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
259        &input, &samplerate, &fftsize)) {
[6a50b9e]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
[72d08ae]274  if (!PyArg_ParseTuple (args,
275        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
276        &input, &samplerate, &fftsize)) {
[6a50b9e]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
[72d08ae]291  if (!PyArg_ParseTuple (args,
292        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
293        &input, &samplerate, &fftsize)) {
[6a50b9e]294    return NULL;
295  }
296
297  output = aubio_freqtobin (input, samplerate, fftsize);
298
299  return (PyObject *)PyFloat_FromDouble (output);
300}
301
[207ed19]302static PyObject *
303Py_zero_crossing_rate (PyObject * self, PyObject * args)
304{
305  PyObject *input;
[569b363]306  fvec_t vec;
[207ed19]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
[569b363]317  if (!PyAubio_ArrayToCFvec(input, &vec)) {
[207ed19]318    return NULL;
319  }
320
321  // compute the function
[df66c37]322  result = PyFloat_FromDouble(aubio_zero_crossing_rate (&vec));
[207ed19]323  if (result == NULL) {
324    return NULL;
325  }
326
327  return result;
328}
329
[ce4bfe3]330static PyObject *
[207ed19]331Py_min_removal(PyObject * self, PyObject * args)
332{
333  PyObject *input;
[569b363]334  fvec_t vec;
[207ed19]335
[ccf8b77]336  if (!PyArg_ParseTuple (args, "O:min_removal", &input)) {
[207ed19]337    return NULL;
338  }
339
340  if (input == NULL) {
341    return NULL;
342  }
343
[569b363]344  if (!PyAubio_ArrayToCFvec(input, &vec)) {
[207ed19]345    return NULL;
346  }
347
348  // compute the function
[569b363]349  fvec_min_removal (&vec);
[615ac7d]350
[207ed19]351  // since this function does not return, we could return None
[9e6695d]352  //Py_RETURN_NONE;
[ce4bfe3]353  // however it is convenient to return the modified vector
[569b363]354  return (PyObject *) PyAubio_CFvecToArray(&vec);
[207ed19]355  // or even without converting it back to an array
[9b23eb31]356  //Py_INCREF(vec);
357  //return (PyObject *)vec;
[207ed19]358}
359
[0a6c211]360static PyMethodDef aubio_methods[] = {
[6a50b9e]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},
[0a6c211]365  {"alpha_norm", Py_alpha_norm, METH_VARARGS, Py_alpha_norm_doc},
[6a50b9e]366  {"zero_crossing_rate", Py_zero_crossing_rate, METH_VARARGS, Py_zero_crossing_rate_doc},
[207ed19]367  {"min_removal", Py_min_removal, METH_VARARGS, Py_min_removal_doc},
[5a7e2c3]368  {"level_lin", Py_aubio_level_lin, METH_VARARGS, Py_aubio_level_lin_doc},
[4615886a]369  {"db_spl", Py_aubio_db_spl, METH_VARARGS, Py_aubio_db_spl_doc},
[31a09d2]370  {"silence_detection", Py_aubio_silence_detection, METH_VARARGS, Py_aubio_silence_detection_doc},
[9c8c8a6]371  {"level_detection", Py_aubio_level_detection, METH_VARARGS, Py_aubio_level_detection_doc},
[913a7f1]372  {"window", Py_aubio_window, METH_VARARGS, Py_aubio_window_doc},
[b532275]373  {"shift", Py_aubio_shift, METH_VARARGS, Py_aubio_shift_doc},
374  {"ishift", Py_aubio_ishift, METH_VARARGS, Py_aubio_ishift_doc},
[bc66f1d]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},
[84fad5a]379  {NULL, NULL, 0, NULL} /* Sentinel */
[0a6c211]380};
381
[2e4ae1d]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
[67537d7]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
[2e4ae1d]413static PyObject *
414initaubio (void)
[0a6c211]415{
[2e4ae1d]416  PyObject *m = NULL;
[0a6c211]417  int err;
418
[7a6521d]419  // fvec is defined in __init__.py
[ce4bfe3]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)
[d27634d]425      || (PyType_Ready (&Py_sourceType) < 0)
[f1100a4]426      || (PyType_Ready (&Py_sinkType) < 0)
[449bff6]427      // generated objects
428      || (generated_types_ready() < 0 )
[615ac7d]429  ) {
[2e4ae1d]430    return m;
[0a6c211]431  }
432
[2e4ae1d]433#if PY_MAJOR_VERSION >= 3
434  m = PyModule_Create(&moduledef);
435#else
[1458de5]436  m = Py_InitModule3 ("_aubio", aubio_methods, aubio_module_doc);
[2e4ae1d]437#endif
[1458de5]438
439  if (m == NULL) {
[2e4ae1d]440    return m;
[1458de5]441  }
442
[0a6c211]443  err = _import_array ();
444  if (err != 0) {
445    fprintf (stderr,
[ad5203c]446        "Unable to import Numpy array from aubio module (error %d)\n", err);
[0a6c211]447  }
448
[9b23eb31]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);
[615ac7d]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);
[d27634d]459  Py_INCREF (&Py_sourceType);
460  PyModule_AddObject (m, "source", (PyObject *) & Py_sourceType);
[f1100a4]461  Py_INCREF (&Py_sinkType);
462  PyModule_AddObject (m, "sink", (PyObject *) & Py_sinkType);
[449bff6]463
[c6388f4]464  PyModule_AddStringConstant(m, "float_type", AUBIO_NPY_SMPL_STR);
[f7e30e8]465  PyModule_AddStringConstant(m, "__version__", DEFINEDSTRING(AUBIO_VERSION));
[c6388f4]466
[7a6521d]467  // add generated objects
[449bff6]468  add_generated_objects(m);
[0d222ee]469
470  // add ufunc
471  add_ufuncs(m);
[2e4ae1d]472
[67537d7]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);
[2e4ae1d]475  return m;
[0a6c211]476}
[2e4ae1d]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.