Merge branch 'master' into feature/pydocstrings
authorPaul Brossier <piem@piem.org>
Fri, 7 Dec 2018 12:16:37 +0000 (13:16 +0100)
committerPaul Brossier <piem@piem.org>
Fri, 7 Dec 2018 12:16:37 +0000 (13:16 +0100)
doc/py_analysis.rst [new file with mode: 0644]
doc/py_spectral.rst [new file with mode: 0644]
doc/py_synth.rst [new file with mode: 0644]
doc/py_temporal.rst [new file with mode: 0644]
doc/python.rst
python/ext/aubio-docstrings.h [new file with mode: 0644]
python/ext/aubio-types.h
python/ext/py-fft.c
python/ext/py-filter.c
python/ext/py-filterbank.c
python/lib/gen_code.py

diff --git a/doc/py_analysis.rst b/doc/py_analysis.rst
new file mode 100644 (file)
index 0000000..47d7ab1
--- /dev/null
@@ -0,0 +1,15 @@
+.. currentmodule:: aubio
+.. default-domain:: py
+
+Analysis
+--------
+
+.. members of generated classes are not shown
+
+.. autoclass:: onset
+
+.. autoclass:: pitch
+
+.. autoclass:: tempo
+
+.. autoclass:: notes
diff --git a/doc/py_spectral.rst b/doc/py_spectral.rst
new file mode 100644 (file)
index 0000000..1697041
--- /dev/null
@@ -0,0 +1,34 @@
+.. currentmodule:: aubio
+.. default-domain:: py
+
+.. members of generated classes are not yet documented
+
+Spectral features
+-----------------
+
+This section contains the documentation for:
+
+- :class:`dct`
+- :class:`fft`
+- :class:`filterbank`
+- :class:`mfcc`
+- :class:`pvoc`
+- :class:`specdesc`
+- :class:`tss`
+
+.. autoclass:: dct
+
+.. autoclass:: fft
+  :members:
+
+.. autoclass:: filterbank
+  :members:
+
+.. autoclass:: mfcc
+
+.. autoclass:: pvoc
+  :members:
+
+.. autoclass:: specdesc
+
+.. autoclass:: tss
diff --git a/doc/py_synth.rst b/doc/py_synth.rst
new file mode 100644 (file)
index 0000000..d7afb24
--- /dev/null
@@ -0,0 +1,9 @@
+.. currentmodule:: aubio
+.. default-domain:: py
+
+Synthesis
+---------
+
+.. autoclass:: sampler
+
+.. autoclass:: wavetable
diff --git a/doc/py_temporal.rst b/doc/py_temporal.rst
new file mode 100644 (file)
index 0000000..9a0bb39
--- /dev/null
@@ -0,0 +1,8 @@
+.. currentmodule:: aubio
+.. default-domain:: py
+
+Digital filters
+---------------
+
+.. autoclass:: digital_filter
+  :members:
index 31aa4a1..cc91244 100644 (file)
@@ -30,6 +30,10 @@ Contents
 
    py_datatypes
    py_io
+   py_temporal
+   py_spectral
+   py_analysis
+   py_synth
    py_utils
    py_examples
 
diff --git a/python/ext/aubio-docstrings.h b/python/ext/aubio-docstrings.h
new file mode 100644 (file)
index 0000000..2929ee1
--- /dev/null
@@ -0,0 +1,143 @@
+#define PYAUBIO_dct_doc \
+    "dct(size=1024)\n"\
+    "\n"\
+    "Compute Discrete Fourier Transorms of Type-II.\n"\
+    "\n"\
+    "Parameters\n"\
+    "----------\n"\
+    "size : int\n"\
+    "    size of the DCT to compute\n"\
+    "\n"\
+    "Example\n"\
+    "-------\n"\
+    ">>> d = aubio.dct(16)\n"\
+    ">>> d.size\n"\
+    "16\n"\
+    ">>> x = aubio.fvec(np.ones(d.size))\n"\
+    ">>> d(x)\n"\
+    "array([4., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n"\
+    "      dtype=float32)\n"\
+    ">>> d.rdo(d(x))\n"\
+    "array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n"\
+    "      dtype=float32)\n"\
+    "\n"\
+    "References\n"\
+    "----------\n"\
+    "`DCT-II in Discrete Cosine Transform\n"\
+    "<https://en.wikipedia.org/wiki/Discrete_cosine_transform#DCT-II>`_\n"\
+    "on Wikipedia.\n"
+
+#define PYAUBIO_mfcc_doc \
+    "mfcc(buf_size=1024, n_filters=40, n_coeffs=13, samplerate=44100)\n"\
+    "\n"\
+    "Compute Mel Frequency Cepstrum Coefficients (MFCC).\n"\
+    "\n"\
+    "`mfcc` creates a callable which takes a `cvec` as input.\n"\
+    "\n"\
+    "If `n_filters = 40`, the filterbank will be initialized with\n"\
+    ":meth:`filterbank.set_mel_coeffs_slaney`. Otherwise, if `n_filters`\n"\
+    "is greater than `0`, it will be initialized with\n"\
+    ":meth:`filterbank.set_mel_coeffs` using `fmin = 0`,\n"\
+    "`fmax = samplerate/`.\n"\
+    "\n"\
+    "Example\n"\
+    "-------\n"\
+    ">>> buf_size = 2048; n_filters = 128; n_coeffs = 13; samplerate = 44100\n"\
+    ">>> mf = aubio.mfcc(buf_size, n_filters, n_coeffs, samplerate)\n"\
+    ">>> fftgrain = aubio.cvec(buf_size)\n"\
+    ">>> mf(fftgrain).shape\n"\
+    "(13,)\n"\
+    ""
+
+#define PYAUBIO_notes_doc \
+    "notes(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
+    "\n"\
+    "Note detection\n"
+
+#define PYAUBIO_onset_doc \
+    "onset(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
+    "\n"\
+    "Onset detection object. `method` should be one of method supported by\n"\
+    ":class:`specdesc`.\n"
+
+#define PYAUBIO_pitch_doc \
+    "pitch(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
+    "\n"\
+    "Pitch detection.\n"\
+    "\n"\
+    "Supported methods: `yinfft`, `yin`, `yinfast`, `fcomb`, `mcomb`,\n"\
+    "`schmitt`, `specacf`, `default` (`yinfft`).\n"
+
+#define PYAUBIO_sampler_doc \
+    "sampler(hop_size=512, samplerate=44100)\n"\
+    "\n"\
+    "Sampler.\n"
+
+#define PYAUBIO_specdesc_doc \
+    "specdesc(method=\"default\", buf_size=1024)\n"\
+    "\n"\
+    "Spectral description functions. Creates a callable that takes a\n"\
+    ":class:`cvec` as input, typically created by :class:`pvoc` for\n"\
+    "overlap and windowing, and returns a single float.\n"\
+    "\n"\
+    "`method` can be any of the values listed below. If `default` is used\n"\
+    "the `hfc` function will be selected.\n"\
+    "\n"\
+    "Onset novelty functions:\n"\
+    "\n"\
+    "- `energy`: local energy,\n"\
+    "- `hfc`: high frequency content,\n"\
+    "- `complex`: complex domain,\n"\
+    "- `phase`: phase-based method,\n"\
+    "- `wphase`: weighted phase deviation,\n"\
+    "- `specdiff`: spectral difference,\n"\
+    "- `kl`: Kullback-Liebler,\n"\
+    "- `mkl`: modified Kullback-Liebler,\n"\
+    "- `specflux`: spectral flux.\n"\
+    "\n"\
+    "Spectral shape functions:\n"\
+    "\n"\
+    "- `centroid`: spectral centroid (barycenter of the norm vector),\n"\
+    "- `spread`: variance around centroid,\n"\
+    "- `skewness`: third order moment,\n"\
+    "- `kurtosis`: a measure of the flatness of the spectrum,\n"\
+    "- `slope`: decreasing rate of the amplitude,\n"\
+    "- `decrease`: perceptual based measurement of the decreasing rate,\n"\
+    "- `rolloff`: 95th energy percentile.\n"\
+    "\n"\
+    "Parameters\n"\
+    "----------\n"\
+    "method : str\n"\
+    "    Onset novelty or spectral shape function.\n"\
+    "buf_size : int\n"\
+    "    Length of the input frame.\n"\
+    "\n"\
+    "Example\n"\
+    "-------\n"\
+    ">>> win_s = 1024; hop_s = win_s // 2\n"\
+    ">>> pv = aubio.pvoc(win_s, hop_s)\n"\
+    ">>> sd = aubio.specdesc(\"mkl\", win_s)\n"\
+    ">>> sd(pv(aubio.fvec(hop_s))).shape\n"\
+    "(1,)\n"\
+    "\n"\
+    "References\n"\
+    "----------\n"\
+    "`Detailed description "\
+    "<https://aubio.org/doc/latest/specdesc_8h.html#details>`_ in\n"\
+    "`aubio API documentation <https://aubio.org/doc/latest/index.html>`_.\n"\
+    ""
+
+#define PYAUBIO_tempo_doc \
+    "tempo(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
+    "\n"\
+    "Tempo detection and beat tracking.\n"
+
+#define PYAUBIO_tss_doc \
+    "tss(buf_size=1024, hop_size=512)\n"\
+    "\n"\
+    "Transient/Steady-state separation.\n"
+
+#define PYAUBIO_wavetable_doc \
+    "wavetable(samplerate=44100, hop_size=512)\n"\
+    "\n"\
+    "Wavetable synthesis.\n"
index 26f8b1d..4458ecc 100644 (file)
@@ -1,6 +1,7 @@
 #include <Python.h>
 #include <structmember.h>
 
+#include "aubio-docstrings.h"
 #include "aubio-generated.h"
 
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
index 8763632..a08af4e 100644 (file)
@@ -1,6 +1,24 @@
 #include "aubio-types.h"
 
-static char Py_fft_doc[] = "fft object";
+static char Py_fft_doc[] = ""
+"fft(size=1024)\n"
+"\n"
+"Compute Fast Fourier Transorms.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"size : int\n"
+"    size of the FFT to compute\n"
+"\n"
+"Example\n"
+"-------\n"
+">>> x = aubio.fvec(512)\n"
+">>> f = aubio.fft(512)\n"
+">>> c = f(x); c\n"
+"aubio cvec of 257 elements\n"
+">>> x2 = f.rdo(c); x2.shape\n"
+"(512,)\n"
+"";
 
 typedef struct
 {
index df78e47..e10a8ed 100644 (file)
@@ -10,7 +10,58 @@ typedef struct
   fvec_t c_out;
 } Py_filter;
 
-static char Py_filter_doc[] = "filter object";
+static char Py_filter_doc[] = ""
+"digital_filter(order=7)\n"
+"\n"
+"Create a digital filter.\n"
+"";
+
+static char Py_filter_set_c_weighting_doc[] = ""
+"set_c_weighting(samplerate)\n"
+"\n"
+"Set filter coefficients to C-weighting.\n"
+"\n"
+"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
+"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 5.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"samplerate : int\n"
+"    Sampling-rate of the input signal, in Hz.\n"
+"";
+
+static char Py_filter_set_a_weighting_doc[] = ""
+"set_a_weighting(samplerate)\n"
+"\n"
+"Set filter coefficients to A-weighting.\n"
+"\n"
+"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
+"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 7.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"samplerate : int\n"
+"    Sampling-rate of the input signal.\n"
+"";
+
+static char Py_filter_set_biquad_doc[] = ""
+"set_biquad(b0, b1, b2, a1, a2)\n"
+"\n"
+"Set biquad coefficients. `order` of the filter should be 3.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"b0 : float\n"
+"    Forward filter coefficient.\n"
+"b1 : float\n"
+"    Forward filter coefficient.\n"
+"b2 : float\n"
+"    Forward filter coefficient.\n"
+"a1 : float\n"
+"    Feedback filter coefficient.\n"
+"a2 : float\n"
+"    Feedback filter coefficient.\n"
+"";
 
 static PyObject *
 Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
@@ -156,11 +207,11 @@ static PyMemberDef Py_filter_members[] = {
 
 static PyMethodDef Py_filter_methods[] = {
   {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
-      "set filter coefficients to C-weighting"},
+      Py_filter_set_c_weighting_doc},
   {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
-      "set filter coefficients to A-weighting"},
+      Py_filter_set_a_weighting_doc},
   {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
-      "set b0, b1, b2, a1, a2 biquad coefficients"},
+      Py_filter_set_biquad_doc},
   {NULL}
 };
 
index 22f2a56..0bd00d0 100644 (file)
@@ -1,6 +1,188 @@
 #include "aubio-types.h"
 
-static char Py_filterbank_doc[] = "filterbank object";
+static char Py_filterbank_doc[] = ""
+"filterbank(n_filters=40, win_s=1024)\n"
+"\n"
+"Create a bank of spectral filters. Each instance is a callable\n"
+"that holds a matrix of coefficients.\n"
+"\n"
+"See also :meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`,\n"
+":meth:`set_mel_coeffs_slaney`, :meth:`set_triangle_bands`, and\n"
+":meth:`set_coeffs`.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"n_filters : int\n"
+"    Number of filters to create.\n"
+"win_s : int\n"
+"    Size of the input spectrum to process.\n"
+"\n"
+"Examples\n"
+"--------\n"
+">>> f = aubio.filterbank(128, 1024)\n"
+">>> f.set_mel_coeffs(44100, 0, 10000)\n"
+">>> c = aubio.cvec(1024)\n"
+">>> f(c).shape\n"
+"(128, )\n"
+"";
+
+static char Py_filterbank_set_triangle_bands_doc[] =""
+"set_triangle_bands(freqs, samplerate)\n"
+"\n"
+"Set triangular bands. The coefficients will be set to triangular\n"
+"overlapping windows using the boundaries specified by `freqs`.\n"
+"\n"
+"`freqs` should contain `n_filters + 2` frequencies in Hz, ordered\n"
+"by value, from smallest to largest. The first element should be greater\n"
+"or equal to zero; the last element should be smaller or equal to\n"
+"`samplerate / 2`.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"freqs: fvec\n"
+"    List of frequencies, in Hz.\n"
+"samplerate : float\n"
+"    Sampling-rate of the expected input.\n"
+"\n"
+"Example\n"
+"-------\n"
+">>> fb = aubio.filterbank(n_filters=100, win_s=2048)\n"
+">>> samplerate = 44100; freqs = np.linspace(0, 20200, 102)\n"
+">>> fb.set_triangle_bands(aubio.fvec(freqs), samplerate)\n"
+"";
+
+static char Py_filterbank_set_mel_coeffs_slaney_doc[] = ""
+"set_mel_coeffs_slaney(samplerate)\n"
+"\n"
+"Set coefficients of filterbank to match Slaney's Auditory Toolbox.\n"
+"\n"
+"The filter coefficients will be set as in Malcolm Slaney's\n"
+"implementation. The filterbank should have been created with\n"
+"`n_filters = 40`.\n"
+"\n"
+"This is approximately equivalent to using :meth:`set_mel_coeffs` with\n"
+"`fmin = 400./3., fmax = 6853.84`.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"samplerate : float\n"
+"    Sampling-rate of the expected input.\n"
+"\n"
+"References\n"
+"----------\n"
+"\n"
+"Malcolm Slaney, `Auditory Toolbox Version 2, Technical Report #1998-010\n"
+"<https://engineering.purdue.edu/~malcolm/interval/1998-010/>`_\n"
+"";
+
+static char Py_filterbank_set_mel_coeffs_doc[] = ""
+"set_mel_coeffs(samplerate, fmin, fmax)\n"
+"\n"
+"Set coefficients of filterbank to linearly spaced mel scale.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"samplerate : float\n"
+"    Sampling-rate of the expected input.\n"
+"fmin : float\n"
+"    Lower frequency boundary of the first filter.\n"
+"fmax : float\n"
+"    Upper frequency boundary of the last filter.\n"
+"\n"
+"See also\n"
+"--------\n"
+"hztomel\n"
+"";
+
+static char Py_filterbank_set_mel_coeffs_htk_doc[] = ""
+"set_mel_coeffs_htk(samplerate, fmin, fmax)\n"
+"\n"
+"Set coefficients of the filters to be linearly spaced in the HTK mel scale.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"samplerate : float\n"
+"    Sampling-rate of the expected input.\n"
+"fmin : float\n"
+"    Lower frequency boundary of the first filter.\n"
+"fmax : float\n"
+"    Upper frequency boundary of the last filter.\n"
+"\n"
+"See also\n"
+"--------\n"
+"hztomel with `htk=True`\n"
+"";
+
+static char Py_filterbank_get_coeffs_doc[] = ""
+"get_coeffs()\n"
+"\n"
+"Get coefficients matrix of filterbank.\n"
+"\n"
+"Returns\n"
+"-------\n"
+"array_like\n"
+"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
+"";
+
+static char Py_filterbank_set_coeffs_doc[] = ""
+"set_coeffs(coeffs)\n"
+"\n"
+"Set coefficients of filterbank.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"coeffs : fmat\n"
+"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
+"";
+
+static char Py_filterbank_set_power_doc[] = ""
+"set_power(power)\n"
+"\n"
+"Set power applied to input spectrum of filterbank.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"power : float\n"
+"    Power to raise input spectrum to before computing the filters.\n"
+"";
+
+static char Py_filterbank_get_power_doc[] = ""
+"get_power()\n"
+"\n"
+"Get power applied to filterbank.\n"
+"\n"
+"Returns\n"
+"-------\n"
+"float\n"
+"    Power parameter.\n"
+"";
+
+static char Py_filterbank_set_norm_doc[] = ""
+"set_norm(norm)\n"
+"\n"
+"Set norm parameter. If set to `0`, the filters will not be normalized.\n"
+"If set to `1`, the filters will be normalized to one. Default to `1`.\n"
+"\n"
+"This function should be called *before* :meth:`set_triangle_bands`,\n"
+":meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`, or\n"
+":meth:`set_mel_coeffs_slaney`.\n"
+"\n"
+"Parameters\n"
+"----------\n"
+"norm : int\n"
+"   `0` to disable, `1` to enable\n"
+"";
+
+static char Py_filterbank_get_norm_doc[] = ""
+"get_norm()\n"
+"\n"
+"Get norm parameter of filterbank.\n"
+"\n"
+"Returns\n"
+"-------\n"
+"float\n"
+"    Norm parameter.\n"
+"";
 
 typedef struct
 {
@@ -289,6 +471,13 @@ Py_filterbank_set_power(Py_filterbank *self, PyObject *args)
 }
 
 static PyObject *
+Py_filterbank_get_power (Py_filterbank * self, PyObject *unused)
+{
+  smpl_t power = aubio_filterbank_get_power(self->o);
+  return (PyObject *)PyFloat_FromDouble (power);
+}
+
+static PyObject *
 Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
 {
   smpl_t norm;
@@ -311,23 +500,34 @@ Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+static PyObject *
+Py_filterbank_get_norm (Py_filterbank * self, PyObject *unused)
+{
+  smpl_t norm = aubio_filterbank_get_norm(self->o);
+  return (PyObject *)PyFloat_FromDouble (norm);
+}
+
 static PyMethodDef Py_filterbank_methods[] = {
   {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
-    METH_VARARGS, "set coefficients of filterbanks"},
+    METH_VARARGS, Py_filterbank_set_triangle_bands_doc},
   {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
-    METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
+    METH_VARARGS, Py_filterbank_set_mel_coeffs_slaney_doc},
   {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
-    METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
+    METH_VARARGS, Py_filterbank_set_mel_coeffs_doc},
   {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
-    METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
+    METH_VARARGS, Py_filterbank_set_mel_coeffs_htk_doc},
   {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
-    METH_NOARGS, "get coefficients of filterbank"},
+    METH_NOARGS, Py_filterbank_get_coeffs_doc},
   {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
-    METH_VARARGS, "set coefficients of filterbank"},
+    METH_VARARGS, Py_filterbank_set_coeffs_doc},
   {"set_power", (PyCFunction) Py_filterbank_set_power,
-    METH_VARARGS, "set power applied to filterbank input spectrum"},
+    METH_VARARGS, Py_filterbank_set_power_doc},
+  {"get_power", (PyCFunction) Py_filterbank_get_power,
+    METH_NOARGS, Py_filterbank_get_power_doc},
   {"set_norm", (PyCFunction) Py_filterbank_set_norm,
-    METH_VARARGS, "set norm applied to filterbank input spectrum"},
+    METH_VARARGS, Py_filterbank_set_norm_doc},
+  {"get_norm", (PyCFunction) Py_filterbank_get_norm,
+    METH_NOARGS, Py_filterbank_get_norm_doc},
   {NULL}
 };
 
index a29a23f..b48f9a0 100644 (file)
@@ -231,11 +231,21 @@ typedef struct{{
         return out.format(do_inputs_list = do_inputs_list, **self.__dict__)
 
     def gen_doc(self):
+        sig = []
+        for p in self.input_params:
+            name = p['name']
+            defval = aubiodefvalue[name].replace('"','\\\"')
+            sig.append("{name}={defval}".format(defval=defval, name=name))
         out = """
-// TODO: add documentation
-static char Py_{shortname}_doc[] = \"undefined\";
+#ifndef PYAUBIO_{shortname}_doc
+#define PYAUBIO_{shortname}_doc "{shortname}({sig})"
+#endif /* PYAUBIO_{shortname}_doc */
+
+static char Py_{shortname}_doc[] = ""
+PYAUBIO_{shortname}_doc
+"";
 """
-        return out.format(**self.__dict__)
+        return out.format(sig=', '.join(sig), **self.__dict__)
 
     def gen_new(self):
         out = """