source: python/ext/py-phasevoc.c @ 1e2811c

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

[py] remove useless check in py-phasevoc.c

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[5652a8c]1#include "aubio-types.h"
[615ac7d]2
[47b465c]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
[51b9c83]56
[202697a]57typedef struct
58{
59  PyObject_HEAD
60  aubio_pvoc_t * o;
61  uint_t win_s;
62  uint_t hop_s;
[569b363]63  fvec_t vecin;
64  cvec_t cvecin;
[307fdfc]65  PyObject *output;
66  cvec_t c_output;
67  PyObject *routput;
68  fvec_t c_routput;
[202697a]69} Py_pvoc;
70
[615ac7d]71
72static PyObject *
73Py_pvoc_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
74{
[0f045b2]75  int win_s = 0, hop_s = 0;
[615ac7d]76  Py_pvoc *self;
[0f045b2]77  static char *kwlist[] = { "win_s", "hop_s", NULL };
[615ac7d]78
[0f045b2]79  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
80          &win_s, &hop_s)) {
[615ac7d]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 (win_s > 0) {
94    self->win_s = win_s;
95  } else if (win_s < 0) {
96    PyErr_SetString (PyExc_ValueError,
97        "can not use negative window size");
98    return NULL;
99  }
100
101  if (hop_s > 0) {
102    self->hop_s = hop_s;
103  } else if (hop_s < 0) {
104    PyErr_SetString (PyExc_ValueError,
105        "can not use negative hop size");
106    return NULL;
107  }
108
[5652a8c]109  return (PyObject *) self;
110}
111
112static int
113Py_pvoc_init (Py_pvoc * self, PyObject * args, PyObject * kwds)
114{
115  self->o = new_aubio_pvoc ( self->win_s, self->hop_s);
116  if (self->o == NULL) {
[3528079]117    // PyErr_Format(PyExc_RuntimeError, ...) was set above by new_ which called
118    // AUBIO_ERR when failing
[5652a8c]119    return -1;
120  }
121
[307fdfc]122  self->output = new_py_cvec(self->win_s);
123  self->routput = new_py_fvec(self->hop_s);
[202697a]124
[5652a8c]125  return 0;
[615ac7d]126}
127
128
[202697a]129static void
130Py_pvoc_del (Py_pvoc *self, PyObject *unused)
131{
[307fdfc]132  Py_XDECREF(self->output);
133  Py_XDECREF(self->routput);
[8cf51c4]134  if (self->o) {
135    del_aubio_pvoc(self->o);
136  }
[5c1200a]137  Py_TYPE(self)->tp_free((PyObject *) self);
[202697a]138}
139
[615ac7d]140
[b5bef11]141static PyObject *
[c04d250]142Py_pvoc_do(Py_pvoc * self, PyObject * args)
[615ac7d]143{
144  PyObject *input;
145
146  if (!PyArg_ParseTuple (args, "O", &input)) {
147    return NULL;
148  }
149
[569b363]150  if (!PyAubio_ArrayToCFvec (input, &(self->vecin) )) {
[615ac7d]151    return NULL;
152  }
153
[99aa353]154  if (self->vecin.length != self->hop_s) {
155    PyErr_Format(PyExc_ValueError,
156                 "input fvec has length %d, but pvoc expects length %d",
157                 self->vecin.length, self->hop_s);
158    return NULL;
159  }
160
[307fdfc]161  Py_INCREF(self->output);
162  if (!PyAubio_PyCvecToCCvec (self->output, &(self->c_output))) {
163    return NULL;
164  }
[615ac7d]165  // compute the function
[307fdfc]166  aubio_pvoc_do (self->o, &(self->vecin), &(self->c_output));
167  return self->output;
[615ac7d]168}
169
[5652a8c]170static PyMemberDef Py_pvoc_members[] = {
[615ac7d]171  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
[47b465c]172    "int: Size of phase vocoder analysis windows, in samples.\n"
173    ""},
[615ac7d]174  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
[47b465c]175    "int: Interval between two analysis, in samples.\n"
176    ""},
[5652a8c]177  { NULL } // sentinel
178};
[615ac7d]179
[307fdfc]180static PyObject *
[c04d250]181Py_pvoc_rdo(Py_pvoc * self, PyObject * args)
[615ac7d]182{
183  PyObject *input;
184  if (!PyArg_ParseTuple (args, "O", &input)) {
185    return NULL;
186  }
187
[92a8800]188  if (!PyAubio_PyCvecToCCvec (input, &(self->cvecin) )) {
[615ac7d]189    return NULL;
190  }
191
[99aa353]192  if (self->cvecin.length != self->win_s / 2 + 1) {
193    PyErr_Format(PyExc_ValueError,
194                 "input cvec has length %d, but pvoc expects length %d",
195                 self->cvecin.length, self->win_s / 2 + 1);
196    return NULL;
197  }
198
[307fdfc]199  Py_INCREF(self->routput);
200  if (!PyAubio_ArrayToCFvec(self->routput, &(self->c_routput)) ) {
201    return NULL;
202  }
[615ac7d]203  // compute the function
[307fdfc]204  aubio_pvoc_rdo (self->o, &(self->cvecin), &(self->c_routput));
205  return self->routput;
[615ac7d]206}
207
[965adee]208static PyObject *
209Pyaubio_pvoc_set_window (Py_pvoc *self, PyObject *args)
210{
211  uint_t err = 0;
212  char_t *window = NULL;
213
214  if (!PyArg_ParseTuple (args, "s", &window)) {
215    return NULL;
216  }
217  err = aubio_pvoc_set_window (self->o, window);
218
219  if (err > 0) {
220    PyErr_SetString (PyExc_ValueError, "error running aubio_pvoc_set_window");
221    return NULL;
222  }
223  Py_RETURN_NONE;
224}
225
[615ac7d]226static PyMethodDef Py_pvoc_methods[] = {
227  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
[47b465c]228    "rdo(fftgrain)\n"
229    "\n"
230    "Read a new spectral grain and resynthesise the next `hop_s`\n"
231    "output samples.\n"
232    "\n"
233    "Parameters\n"
234    "----------\n"
235    "fftgrain : cvec\n"
236    "    new input `cvec` to synthesize from, should be of size `win_s/2+1`\n"
237    "\n"
238    "Returns\n"
239    "-------\n"
240    "fvec\n"
241    "    re-synthesised output of shape `(hop_s,)`\n"
242    "\n"
243    "Example\n"
244    "-------\n"
245    ">>> pv = aubio.pvoc(2048, 512)\n"
246    ">>> out = pv.rdo(aubio.cvec(2048))\n"
247    ">>> out.shape\n"
248    "(512,)\n"
249    ""},
250  {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS,
251    "set_window(window_type)\n"
252    "\n"
253    "Set window function\n"
254    "\n"
255    "Parameters\n"
256    "----------\n"
257    "window_type : str\n"
258    "    the window type to use for this phase vocoder\n"
259    "\n"
260    "Raises\n"
261    "------\n"
262    "ValueError\n"
263    "    If an unknown window type was given.\n"
264    "\n"
265    "See Also\n"
266    "--------\n"
267    "window : create a window.\n"
268    ""},
[615ac7d]269  {NULL}
270};
271
[5652a8c]272PyTypeObject Py_pvocType = {
273  PyVarObject_HEAD_INIT (NULL, 0)
274  "aubio.pvoc",
275  sizeof (Py_pvoc),
276  0,
277  (destructor) Py_pvoc_del,
278  0,
279  0,
280  0,
281  0,
282  0,
283  0,
284  0,
285  0,
286  0,
287  (ternaryfunc)Py_pvoc_do,
288  0,
289  0,
290  0,
291  0,
292  Py_TPFLAGS_DEFAULT,
293  Py_pvoc_doc,
294  0,
295  0,
296  0,
297  0,
298  0,
299  0,
300  Py_pvoc_methods,
301  Py_pvoc_members,
302  0,
303  0,
304  0,
305  0,
306  0,
307  0,
308  (initproc) Py_pvoc_init,
309  0,
310  Py_pvoc_new,
[0e70ef9]311  0,
312  0,
313  0,
314  0,
315  0,
316  0,
317  0,
318  0,
319  0,
[5652a8c]320};
Note: See TracBrowser for help on using the repository browser.