source: python/ext/py-phasevoc.c @ 47b465c

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5
Last change on this file since 47b465c was 47b465c, checked in by Paul Brossier <piem@piem.org>, 5 years ago

[python] add docstrings for pvoc

  • Property mode set to 100644
File size: 6.8 KB
Line 
1#include "aubio-types.h"
2
3static char Py_pvoc_doc[] = ""
4"pvoc(win_s=512, hop_s=256)\n"
5"\n"
6"Phase vocoder.\n"
7"\n"
8"`pvoc` creates callable object implements a phase vocoder [1]_,\n"
9"using the tricks detailed in [2]_.\n"
10"\n"
11"The call function takes one input of type `fvec` and of size\n"
12"`hop_s`, and returns a `cvec` of length `win_s//2+1`.\n"
13"\n"
14"Parameters\n"
15"----------\n"
16"win_s : int\n"
17"  number of channels in the phase-vocoder.\n"
18"hop_s : int\n"
19"  number of samples expected between each call\n"
20"\n"
21"Examples\n"
22"--------\n"
23">>> x = aubio.fvec(256)\n"
24">>> pv = aubio.pvoc(512, 256)\n"
25">>> pv(x)\n"
26"aubio cvec of 257 elements\n"
27"\n"
28"Default values for hop_s and win_s are provided:\n"
29"\n"
30">>> pv = aubio.pvoc()\n"
31">>> pv.win_s, pv.hop_s\n"
32"512, 256\n"
33"\n"
34"A `cvec` can be resynthesised using `rdo()`:\n"
35"\n"
36">>> pv = aubio.pvoc(512, 256)\n"
37">>> y = aubio.cvec(512)\n"
38">>> x_reconstructed = pv.rdo(y)\n"
39">>> x_reconstructed.shape\n"
40"(256,)\n"
41"\n"
42"References\n"
43"----------\n"
44".. [1] James A. Moorer. The use of the phase vocoder in computer music\n"
45"   applications. `Journal of the Audio Engineering Society`,\n"
46"   26(1/2):42–45, 1978.\n"
47".. [2] Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional\n"
48"   (?) implementations of a phase vocoder: the tricks of the trade.\n"
49"   In `Proceedings of the International Conference on Digital Audio\n"
50"   Effects` (DAFx-00), pages 37–44, University of Verona, Italy, 2000.\n"
51"   (`online version <"
52"https://www.cs.princeton.edu/courses/archive/spr09/cos325/Bernardini.pdf"
53">`_).\n"
54"";
55
56
57typedef struct
58{
59  PyObject_HEAD
60  aubio_pvoc_t * o;
61  uint_t win_s;
62  uint_t hop_s;
63  fvec_t vecin;
64  cvec_t cvecin;
65  PyObject *output;
66  cvec_t c_output;
67  PyObject *routput;
68  fvec_t c_routput;
69} Py_pvoc;
70
71
72static PyObject *
73Py_pvoc_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
74{
75  int win_s = 0, hop_s = 0;
76  Py_pvoc *self;
77  static char *kwlist[] = { "win_s", "hop_s", NULL };
78
79  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
80          &win_s, &hop_s)) {
81    return NULL;
82  }
83
84  self = (Py_pvoc *) type->tp_alloc (type, 0);
85
86  if (self == NULL) {
87    return NULL;
88  }
89
90  self->win_s = Py_default_vector_length;
91  self->hop_s = Py_default_vector_length/2;
92
93  if (self == NULL) {
94    return NULL;
95  }
96
97  if (win_s > 0) {
98    self->win_s = win_s;
99  } else if (win_s < 0) {
100    PyErr_SetString (PyExc_ValueError,
101        "can not use negative window size");
102    return NULL;
103  }
104
105  if (hop_s > 0) {
106    self->hop_s = hop_s;
107  } else if (hop_s < 0) {
108    PyErr_SetString (PyExc_ValueError,
109        "can not use negative hop size");
110    return NULL;
111  }
112
113  return (PyObject *) self;
114}
115
116static int
117Py_pvoc_init (Py_pvoc * self, PyObject * args, PyObject * kwds)
118{
119  self->o = new_aubio_pvoc ( self->win_s, self->hop_s);
120  if (self->o == NULL) {
121    // PyErr_Format(PyExc_RuntimeError, ...) was set above by new_ which called
122    // AUBIO_ERR when failing
123    return -1;
124  }
125
126  self->output = new_py_cvec(self->win_s);
127  self->routput = new_py_fvec(self->hop_s);
128
129  return 0;
130}
131
132
133static void
134Py_pvoc_del (Py_pvoc *self, PyObject *unused)
135{
136  Py_XDECREF(self->output);
137  Py_XDECREF(self->routput);
138  if (self->o) {
139    del_aubio_pvoc(self->o);
140  }
141  Py_TYPE(self)->tp_free((PyObject *) self);
142}
143
144
145static PyObject *
146Py_pvoc_do(Py_pvoc * self, PyObject * args)
147{
148  PyObject *input;
149
150  if (!PyArg_ParseTuple (args, "O", &input)) {
151    return NULL;
152  }
153
154  if (!PyAubio_ArrayToCFvec (input, &(self->vecin) )) {
155    return NULL;
156  }
157
158  if (self->vecin.length != self->hop_s) {
159    PyErr_Format(PyExc_ValueError,
160                 "input fvec has length %d, but pvoc expects length %d",
161                 self->vecin.length, self->hop_s);
162    return NULL;
163  }
164
165  Py_INCREF(self->output);
166  if (!PyAubio_PyCvecToCCvec (self->output, &(self->c_output))) {
167    return NULL;
168  }
169  // compute the function
170  aubio_pvoc_do (self->o, &(self->vecin), &(self->c_output));
171  return self->output;
172}
173
174static PyMemberDef Py_pvoc_members[] = {
175  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
176    "int: Size of phase vocoder analysis windows, in samples.\n"
177    ""},
178  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
179    "int: Interval between two analysis, in samples.\n"
180    ""},
181  { NULL } // sentinel
182};
183
184static PyObject *
185Py_pvoc_rdo(Py_pvoc * self, PyObject * args)
186{
187  PyObject *input;
188  if (!PyArg_ParseTuple (args, "O", &input)) {
189    return NULL;
190  }
191
192  if (!PyAubio_PyCvecToCCvec (input, &(self->cvecin) )) {
193    return NULL;
194  }
195
196  if (self->cvecin.length != self->win_s / 2 + 1) {
197    PyErr_Format(PyExc_ValueError,
198                 "input cvec has length %d, but pvoc expects length %d",
199                 self->cvecin.length, self->win_s / 2 + 1);
200    return NULL;
201  }
202
203  Py_INCREF(self->routput);
204  if (!PyAubio_ArrayToCFvec(self->routput, &(self->c_routput)) ) {
205    return NULL;
206  }
207  // compute the function
208  aubio_pvoc_rdo (self->o, &(self->cvecin), &(self->c_routput));
209  return self->routput;
210}
211
212static PyObject *
213Pyaubio_pvoc_set_window (Py_pvoc *self, PyObject *args)
214{
215  uint_t err = 0;
216  char_t *window = NULL;
217
218  if (!PyArg_ParseTuple (args, "s", &window)) {
219    return NULL;
220  }
221  err = aubio_pvoc_set_window (self->o, window);
222
223  if (err > 0) {
224    PyErr_SetString (PyExc_ValueError, "error running aubio_pvoc_set_window");
225    return NULL;
226  }
227  Py_RETURN_NONE;
228}
229
230static PyMethodDef Py_pvoc_methods[] = {
231  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
232    "rdo(fftgrain)\n"
233    "\n"
234    "Read a new spectral grain and resynthesise the next `hop_s`\n"
235    "output samples.\n"
236    "\n"
237    "Parameters\n"
238    "----------\n"
239    "fftgrain : cvec\n"
240    "    new input `cvec` to synthesize from, should be of size `win_s/2+1`\n"
241    "\n"
242    "Returns\n"
243    "-------\n"
244    "fvec\n"
245    "    re-synthesised output of shape `(hop_s,)`\n"
246    "\n"
247    "Example\n"
248    "-------\n"
249    ">>> pv = aubio.pvoc(2048, 512)\n"
250    ">>> out = pv.rdo(aubio.cvec(2048))\n"
251    ">>> out.shape\n"
252    "(512,)\n"
253    ""},
254  {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS,
255    "set_window(window_type)\n"
256    "\n"
257    "Set window function\n"
258    "\n"
259    "Parameters\n"
260    "----------\n"
261    "window_type : str\n"
262    "    the window type to use for this phase vocoder\n"
263    "\n"
264    "Raises\n"
265    "------\n"
266    "ValueError\n"
267    "    If an unknown window type was given.\n"
268    "\n"
269    "See Also\n"
270    "--------\n"
271    "window : create a window.\n"
272    ""},
273  {NULL}
274};
275
276PyTypeObject Py_pvocType = {
277  PyVarObject_HEAD_INIT (NULL, 0)
278  "aubio.pvoc",
279  sizeof (Py_pvoc),
280  0,
281  (destructor) Py_pvoc_del,
282  0,
283  0,
284  0,
285  0,
286  0,
287  0,
288  0,
289  0,
290  0,
291  (ternaryfunc)Py_pvoc_do,
292  0,
293  0,
294  0,
295  0,
296  Py_TPFLAGS_DEFAULT,
297  Py_pvoc_doc,
298  0,
299  0,
300  0,
301  0,
302  0,
303  0,
304  Py_pvoc_methods,
305  Py_pvoc_members,
306  0,
307  0,
308  0,
309  0,
310  0,
311  0,
312  (initproc) Py_pvoc_init,
313  0,
314  Py_pvoc_new,
315  0,
316  0,
317  0,
318  0,
319  0,
320  0,
321  0,
322  0,
323  0,
324};
Note: See TracBrowser for help on using the repository browser.