source: python/ext/py-sink.c @ 98d7aaa

feature/autosinkfeature/constantqfeature/pitchshiftfeature/timestretch
Last change on this file since 98d7aaa was 98d7aaa, checked in by Paul Brossier <piem@piem.org>, 6 months ago

[py] check sink was created before calling del_aubio_sink

  • Property mode set to 100644
File size: 6.5 KB
Line 
1#include "aubio-types.h"
2
3typedef struct
4{
5  PyObject_HEAD
6  aubio_sink_t * o;
7  char_t* uri;
8  uint_t samplerate;
9  uint_t channels;
10  fvec_t write_data;
11  fmat_t mwrite_data;
12} Py_sink;
13
14static char Py_sink_doc[] = ""
15"sink(path, samplerate=44100, channels=1)\n"
16"\n"
17"Write audio samples to file.\n"
18"\n"
19"Parameters\n"
20"----------\n"
21"path : str\n"
22"   Pathname of the file to be opened for writing.\n"
23"samplerate : int\n"
24"   Sampling rate of the file, in Hz.\n"
25"channels : int\n"
26"   Number of channels to create the file with.\n"
27"\n"
28"Examples\n"
29"--------\n"
30"\n"
31"Create a new sink at 44100Hz, mono:\n"
32"\n"
33">>> snk = aubio.sink('out.wav')\n"
34"\n"
35"Create a new sink at 32000Hz, stereo, write 100 samples into it:\n"
36"\n"
37">>> snk = aubio.sink('out.wav', samplerate=16000, channels=3)\n"
38">>> snk(aubio.fvec(100), 100)\n"
39"\n"
40"Open a new sink at 48000Hz, stereo, write `1234` samples into it:\n"
41"\n"
42">>> with aubio.sink('out.wav', samplerate=48000, channels=2) as src:\n"
43"...     snk(aubio.fvec(1024), 1024)\n"
44"...     snk(aubio.fvec(210), 210)\n"
45"...\n"
46"\n"
47"See also\n"
48"--------\n"
49"source: read audio samples from a file.\n"
50"\n";
51
52static char Py_sink_do_doc[] = ""
53"do(vec, write)\n"
54"\n"
55"Write a single channel vector to sink.\n"
56"\n"
57"Parameters\n"
58"----------\n"
59"vec : fvec\n"
60"   input vector `(n,)` where `n >= 0`.\n"
61"write : int\n"
62"   Number of samples to write.\n"
63"";
64
65static char Py_sink_do_multi_doc[] = ""
66"do_multi(mat, write)\n"
67"\n"
68"Write a matrix containing vectors from multiple channels to sink.\n"
69"\n"
70"Parameters\n"
71"----------\n"
72"mat : numpy.ndarray\n"
73"   input matrix of shape `(channels, n)`, where `n >= 0`.\n"
74"write : int\n"
75"   Number of frames to write.\n"
76"";
77
78static char Py_sink_close_doc[] = ""
79"close()\n"
80"\n"
81"Close this sink now.\n"
82"\n"
83"By default, the sink will be closed before being deleted.\n"
84"Explicitely closing a sink can be useful to control the number\n"
85"of files simultaneously opened.\n"
86"";
87
88static PyObject *
89Py_sink_new (PyTypeObject * pytype, PyObject * args, PyObject * kwds)
90{
91  Py_sink *self;
92  char_t* uri = NULL;
93  uint_t samplerate = 0;
94  uint_t channels = 0;
95  static char *kwlist[] = { "uri", "samplerate", "channels", NULL };
96
97  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|sII", kwlist,
98          &uri, &samplerate, &channels)) {
99    return NULL;
100  }
101
102  self = (Py_sink *) pytype->tp_alloc (pytype, 0);
103
104  if (self == NULL) {
105    return NULL;
106  }
107
108  self->uri = NULL;
109  if (uri != NULL) {
110    self->uri = (char_t *)malloc(sizeof(char_t) * (strnlen(uri, PATH_MAX) + 1));
111    strncpy(self->uri, uri, strnlen(uri, PATH_MAX) + 1);
112  }
113
114  self->samplerate = Py_aubio_default_samplerate;
115  if (samplerate != 0) {
116    self->samplerate = samplerate;
117  }
118
119  self->channels = 1;
120  if (channels != 0) {
121    self->channels = channels;
122  }
123
124  return (PyObject *) self;
125}
126
127static int
128Py_sink_init (Py_sink * self, PyObject * args, PyObject * kwds)
129{
130  self->o = new_aubio_sink ( self->uri, 0 );
131  if (self->o == NULL) {
132    // error string was set in new_aubio_sink
133    return -1;
134  }
135  if (aubio_sink_preset_channels(self->o, self->channels) != 0) {
136    // error string was set in aubio_sink_preset_channels
137    return -1;
138  }
139  if (aubio_sink_preset_samplerate(self->o, self->samplerate) != 0) {
140    // error string was set in aubio_sink_preset_samplerate
141    return -1;
142  }
143
144  self->samplerate = aubio_sink_get_samplerate ( self->o );
145  self->channels = aubio_sink_get_channels ( self->o );
146
147  return 0;
148}
149
150static void
151Py_sink_del (Py_sink *self, PyObject *unused)
152{
153  if (self->o) {
154    del_aubio_sink(self->o);
155    free(self->mwrite_data.data);
156  }
157  if (self->uri) {
158    free(self->uri);
159  }
160  Py_TYPE(self)->tp_free((PyObject *) self);
161}
162
163/* function Py_sink_do */
164static PyObject *
165Py_sink_do(Py_sink * self, PyObject * args)
166{
167  /* input vectors python prototypes */
168  PyObject * write_data_obj;
169
170  /* input vectors prototypes */
171  uint_t write;
172
173
174  if (!PyArg_ParseTuple (args, "OI", &write_data_obj, &write)) {
175    return NULL;
176  }
177
178  /* input vectors parsing */
179  if (!PyAubio_ArrayToCFvec(write_data_obj, &(self->write_data))) {
180    return NULL;
181  }
182
183
184  /* compute _do function */
185  aubio_sink_do (self->o, &(self->write_data), write);
186
187  Py_RETURN_NONE;
188}
189
190/* function Py_sink_do_multi */
191static PyObject *
192Py_sink_do_multi(Py_sink * self, PyObject * args)
193{
194  /* input vectors python prototypes */
195  PyObject * write_data_obj;
196
197  /* input vectors prototypes */
198  uint_t write;
199
200
201  if (!PyArg_ParseTuple (args, "OI", &write_data_obj, &write)) {
202    return NULL;
203  }
204
205
206  /* input vectors parsing */
207  if (!PyAubio_ArrayToCFmat(write_data_obj, &(self->mwrite_data))) {
208    return NULL;
209  }
210
211  /* compute _do function */
212  aubio_sink_do_multi (self->o, &(self->mwrite_data), write);
213  Py_RETURN_NONE;
214}
215
216static PyMemberDef Py_sink_members[] = {
217  {"uri", T_STRING, offsetof (Py_sink, uri), READONLY,
218    "str (read-only): Path at which the sink was created."},
219  {"samplerate", T_INT, offsetof (Py_sink, samplerate), READONLY,
220    "int (read-only): Samplerate at which the sink was created."},
221  {"channels", T_INT, offsetof (Py_sink, channels), READONLY,
222    "int (read-only): Number of channels with which the sink was created."},
223  { NULL } // sentinel
224};
225
226static PyObject *
227Pyaubio_sink_close (Py_sink *self, PyObject *unused)
228{
229  aubio_sink_close (self->o);
230  Py_RETURN_NONE;
231}
232
233static char Pyaubio_sink_enter_doc[] = "";
234static PyObject* Pyaubio_sink_enter(Py_sink *self, PyObject *unused) {
235  Py_INCREF(self);
236  return (PyObject*)self;
237}
238
239static char Pyaubio_sink_exit_doc[] = "";
240static PyObject* Pyaubio_sink_exit(Py_sink *self, PyObject *unused) {
241  return Pyaubio_sink_close(self, unused);
242}
243
244static PyMethodDef Py_sink_methods[] = {
245  {"do", (PyCFunction) Py_sink_do, METH_VARARGS, Py_sink_do_doc},
246  {"do_multi", (PyCFunction) Py_sink_do_multi, METH_VARARGS, Py_sink_do_multi_doc},
247  {"close", (PyCFunction) Pyaubio_sink_close, METH_NOARGS, Py_sink_close_doc},
248  {"__enter__", (PyCFunction)Pyaubio_sink_enter, METH_NOARGS,
249    Pyaubio_sink_enter_doc},
250  {"__exit__",  (PyCFunction)Pyaubio_sink_exit, METH_VARARGS,
251    Pyaubio_sink_exit_doc},
252  {NULL} /* sentinel */
253};
254
255PyTypeObject Py_sinkType = {
256  PyVarObject_HEAD_INIT (NULL, 0)
257  "aubio.sink",
258  sizeof (Py_sink),
259  0,
260  (destructor) Py_sink_del,
261  0,
262  0,
263  0,
264  0,
265  0,
266  0,
267  0,
268  0,
269  0,
270  (ternaryfunc)Py_sink_do,
271  0,
272  0,
273  0,
274  0,
275  Py_TPFLAGS_DEFAULT,
276  Py_sink_doc,
277  0,
278  0,
279  0,
280  0,
281  0,
282  0,
283  Py_sink_methods,
284  Py_sink_members,
285  0,
286  0,
287  0,
288  0,
289  0,
290  0,
291  (initproc) Py_sink_init,
292  0,
293  Py_sink_new,
294  0,
295  0,
296  0,
297  0,
298  0,
299  0,
300  0,
301  0,
302  0,
303};
Note: See TracBrowser for help on using the repository browser.