source: python/ext/py-phasevoc.c @ 18278232

feature/crepe_org
Last change on this file since 18278232 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
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 (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
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) {
117    // PyErr_Format(PyExc_RuntimeError, ...) was set above by new_ which called
118    // AUBIO_ERR when failing
119    return -1;
120  }
121
122  self->output = new_py_cvec(self->win_s);
123  self->routput = new_py_fvec(self->hop_s);
124
125  return 0;
126}
127
128
129static void
130Py_pvoc_del (Py_pvoc *self, PyObject *unused)
131{
132  Py_XDECREF(self->output);
133  Py_XDECREF(self->routput);
134  if (self->o) {
135    del_aubio_pvoc(self->o);
136  }
137  Py_TYPE(self)->tp_free((PyObject *) self);
138}
139
140
141static PyObject *
142Py_pvoc_do(Py_pvoc * self, PyObject * args)
143{
144  PyObject *input;
145
146  if (!PyArg_ParseTuple (args, "O", &input)) {
147    return NULL;
148  }
149
150  if (!PyAubio_ArrayToCFvec (input, &(self->vecin) )) {
151    return NULL;
152  }
153
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
161  Py_INCREF(self->output);
162  if (!PyAubio_PyCvecToCCvec (self->output, &(self->c_output))) {
163    return NULL;
164  }
165  // compute the function
166  aubio_pvoc_do (self->o, &(self->vecin), &(self->c_output));
167  return self->output;
168}
169
170static PyMemberDef Py_pvoc_members[] = {
171  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
172    "int: Size of phase vocoder analysis windows, in samples.\n"
173    ""},
174  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
175    "int: Interval between two analysis, in samples.\n"
176    ""},
177  { NULL } // sentinel
178};
179
180static PyObject *
181Py_pvoc_rdo(Py_pvoc * self, PyObject * args)
182{
183  PyObject *input;
184  if (!PyArg_ParseTuple (args, "O", &input)) {
185    return NULL;
186  }
187
188  if (!PyAubio_PyCvecToCCvec (input, &(self->cvecin) )) {
189    return NULL;
190  }
191
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
199  Py_INCREF(self->routput);
200  if (!PyAubio_ArrayToCFvec(self->routput, &(self->c_routput)) ) {
201    return NULL;
202  }
203  // compute the function
204  aubio_pvoc_rdo (self->o, &(self->cvecin), &(self->c_routput));
205  return self->routput;
206}
207
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
226static PyMethodDef Py_pvoc_methods[] = {
227  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
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    ""},
269  {NULL}
270};
271
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,
311  0,
312  0,
313  0,
314  0,
315  0,
316  0,
317  0,
318  0,
319  0,
320};
Note: See TracBrowser for help on using the repository browser.