Chris@26
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@26
|
2
|
Chris@26
|
3 /*
|
Chris@26
|
4 VampyHost
|
Chris@26
|
5
|
Chris@26
|
6 Use Vamp audio analysis plugins in Python
|
Chris@26
|
7
|
Chris@26
|
8 Gyorgy Fazekas and Chris Cannam
|
Chris@26
|
9 Centre for Digital Music, Queen Mary, University of London
|
Chris@117
|
10 Copyright 2008-2015 Queen Mary, University of London
|
Chris@26
|
11
|
Chris@26
|
12 Permission is hereby granted, free of charge, to any person
|
Chris@26
|
13 obtaining a copy of this software and associated documentation
|
Chris@26
|
14 files (the "Software"), to deal in the Software without
|
Chris@26
|
15 restriction, including without limitation the rights to use, copy,
|
Chris@26
|
16 modify, merge, publish, distribute, sublicense, and/or sell copies
|
Chris@26
|
17 of the Software, and to permit persons to whom the Software is
|
Chris@26
|
18 furnished to do so, subject to the following conditions:
|
Chris@26
|
19
|
Chris@26
|
20 The above copyright notice and this permission notice shall be
|
Chris@26
|
21 included in all copies or substantial portions of the Software.
|
Chris@26
|
22
|
Chris@26
|
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Chris@26
|
24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Chris@26
|
25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Chris@26
|
26 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
Chris@26
|
27 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
Chris@26
|
28 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Chris@26
|
29 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Chris@26
|
30
|
Chris@26
|
31 Except as contained in this notice, the names of the Centre for
|
Chris@26
|
32 Digital Music; Queen Mary, University of London; and the authors
|
Chris@26
|
33 shall not be used in advertising or otherwise to promote the sale,
|
Chris@26
|
34 use or other dealings in this Software without prior written
|
Chris@26
|
35 authorization.
|
Chris@26
|
36 */
|
Chris@26
|
37
|
Chris@26
|
38 #include "PyRealTime.h"
|
Chris@30
|
39
|
Chris@26
|
40 #include <string>
|
Chris@26
|
41
|
Chris@26
|
42 using namespace std;
|
Chris@26
|
43 using namespace Vamp;
|
Chris@26
|
44
|
Chris@124
|
45 #if (PY_MAJOR_VERSION >= 3)
|
Chris@124
|
46 #define PyInt_AS_LONG PyLong_AS_LONG
|
Chris@124
|
47 #define PyInt_FromSsize_t PyLong_FromSsize_t
|
Chris@124
|
48 #endif
|
Chris@124
|
49
|
Chris@26
|
50 /* CONSTRUCTOR: New RealTime object from sec and nsec */
|
Chris@26
|
51 static PyObject*
|
Chris@26
|
52 RealTime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
Chris@26
|
53 {
|
Chris@124
|
54 int sec = 0;
|
Chris@124
|
55 int nsec = 0;
|
Chris@124
|
56 int unaryInt = 0;
|
Chris@26
|
57 double unary = 0;
|
Chris@26
|
58 const char *fmt = NULL;
|
Chris@26
|
59
|
Chris@124
|
60 if (!PyArg_ParseTuple(args, ":RealTime.new ")) { // zero time
|
Chris@26
|
61
|
Chris@124
|
62 PyErr_Clear();
|
Chris@124
|
63
|
Chris@124
|
64 /// new RealTime from exact ('format',int) e.g. ('milliseconds',200)
|
Chris@124
|
65 if (!PyArg_ParseTuple(args, "si:RealTime.new ",
|
Chris@124
|
66 (const char *) &fmt,
|
Chris@124
|
67 (int *) &unaryInt)) {
|
Chris@124
|
68
|
Chris@124
|
69 PyErr_Clear();
|
Chris@124
|
70
|
Chris@124
|
71 /// new RealTime from ('format',float) e.g. ('seconds',2.34123)
|
Chris@124
|
72 if (!PyArg_ParseTuple(args, "sd:RealTime.new ",
|
Chris@124
|
73 (const char *) &fmt,
|
Chris@124
|
74 (double *) &unary)) {
|
Chris@124
|
75
|
Chris@124
|
76 PyErr_Clear();
|
Chris@124
|
77
|
Chris@124
|
78 /// new RealTime from (sec{int},nsec{int}) e.g. (2,34)
|
Chris@124
|
79 if (!PyArg_ParseTuple(args, "ii:RealTime.new ",
|
Chris@124
|
80 (int*) &sec,
|
Chris@124
|
81 (int*) &nsec)) {
|
Chris@124
|
82
|
Chris@124
|
83 PyErr_SetString(PyExc_TypeError,
|
Chris@124
|
84 "RealTime constructor requires either (sec,nsec) integer tuple, or ('format',float) where 'format' is 'seconds' or 'milliseconds'");
|
Chris@124
|
85 return NULL;
|
Chris@124
|
86 }
|
Chris@124
|
87 }
|
Chris@124
|
88 }
|
Chris@26
|
89 }
|
Chris@26
|
90
|
Chris@87
|
91 PyErr_Clear();
|
Chris@26
|
92
|
Chris@124
|
93 // Using PyObject_New because we use PyObject_Del to delete in the
|
Chris@124
|
94 // destructor
|
Chris@124
|
95 RealTimeObject *self = PyObject_New(RealTimeObject, &RealTime_Type);
|
Chris@124
|
96 PyObject_Init((PyObject *)self, &RealTime_Type);
|
Chris@39
|
97
|
Chris@26
|
98 if (self == NULL) return NULL;
|
Chris@26
|
99
|
Chris@26
|
100 self->rt = NULL;
|
Chris@26
|
101
|
Chris@26
|
102 if (sec == 0 && nsec == 0 && fmt == 0)
|
Chris@39
|
103 self->rt = new RealTime();
|
Chris@26
|
104 else if (fmt == 0)
|
Chris@39
|
105 self->rt = new RealTime(sec,nsec);
|
Chris@26
|
106 else {
|
Chris@26
|
107 /// new RealTime from seconds or milliseconds: i.e. >>>RealTime('seconds',12.3)
|
Chris@39
|
108 if (!string(fmt).compare("float") ||
|
Chris@124
|
109 !string(fmt).compare("seconds")) {
|
Chris@26
|
110
|
Chris@124
|
111 if (unaryInt != 0) {
|
Chris@124
|
112 self->rt = new RealTime(RealTime::fromMilliseconds(unaryInt * 1000));
|
Chris@124
|
113 } else {
|
Chris@124
|
114 self->rt = new RealTime(RealTime::fromSeconds(unary));
|
Chris@124
|
115 }
|
Chris@124
|
116
|
Chris@124
|
117 } else if (!string(fmt).compare("milliseconds")) {
|
Chris@124
|
118
|
Chris@124
|
119 if (unaryInt != 0) {
|
Chris@124
|
120 self->rt = new RealTime(RealTime::fromMilliseconds(unaryInt));
|
Chris@124
|
121 } else {
|
Chris@124
|
122 self->rt = new RealTime(RealTime::fromSeconds(unary / 1000.0));
|
Chris@124
|
123 }
|
Chris@124
|
124 }
|
Chris@26
|
125 }
|
Chris@26
|
126
|
Chris@26
|
127 if (!self->rt) {
|
Chris@39
|
128 PyErr_SetString(PyExc_TypeError,
|
Chris@39
|
129 "RealTime initialised with wrong arguments.");
|
Chris@39
|
130 return NULL;
|
Chris@26
|
131 }
|
Chris@26
|
132
|
Chris@26
|
133 return (PyObject *) self;
|
Chris@26
|
134 }
|
Chris@26
|
135
|
Chris@26
|
136 /* DESTRUCTOR: delete type object */
|
Chris@26
|
137 static void
|
Chris@26
|
138 RealTimeObject_dealloc(RealTimeObject *self)
|
Chris@26
|
139 {
|
Chris@124
|
140 delete self->rt; // delete the C object
|
Chris@124
|
141
|
Chris@124
|
142 // "If the type is not subtypable (doesn’t have the
|
Chris@124
|
143 // Py_TPFLAGS_BASETYPE flag bit set), it is permissible to call
|
Chris@124
|
144 // the object deallocator directly instead of via tp_free"
|
Chris@124
|
145 PyObject_Del(self); // delete the Python object (original)
|
Chris@26
|
146 }
|
Chris@26
|
147
|
Chris@26
|
148 /* RealTime Object's Methods */
|
Chris@26
|
149 //these are internals not exposed by the module but the object
|
Chris@26
|
150
|
Chris@26
|
151 /* Returns a Tuple containing sec and nsec values */
|
Chris@26
|
152 static PyObject *
|
Chris@26
|
153 RealTime_values(RealTimeObject *self)
|
Chris@26
|
154 {
|
Chris@134
|
155 return Py_BuildValue("(ii)", self->rt->sec, self->rt->nsec);
|
Chris@26
|
156 }
|
Chris@26
|
157
|
Chris@26
|
158 /* Returns a Text representation */
|
Chris@26
|
159 static PyObject *
|
Chris@26
|
160 RealTime_toString(RealTimeObject *self, PyObject *args)
|
Chris@26
|
161 {
|
Chris@134
|
162 return Py_BuildValue("s", self->rt->toText().c_str());
|
Chris@26
|
163 }
|
Chris@26
|
164
|
Chris@26
|
165 /* Frame representation */
|
Chris@26
|
166 static PyObject *
|
Chris@26
|
167 RealTime_toFrame(PyObject *self, PyObject *args)
|
Chris@26
|
168 {
|
Chris@26
|
169 unsigned int samplerate;
|
Chris@39
|
170
|
Chris@134
|
171 if (!PyArg_ParseTuple(args, "I:realtime.toFrame object ",
|
Chris@134
|
172 (unsigned int *) &samplerate)) {
|
Chris@39
|
173 PyErr_SetString(PyExc_ValueError,"Integer Sample Rate Required.");
|
Chris@39
|
174 return NULL;
|
Chris@26
|
175 }
|
Chris@39
|
176
|
Chris@26
|
177 return Py_BuildValue("k",
|
Chris@39
|
178 RealTime::realTime2Frame(
|
Chris@39
|
179 *(const RealTime*) ((RealTimeObject*)self)->rt,
|
Chris@39
|
180 (unsigned int) samplerate));
|
Chris@26
|
181 }
|
Chris@26
|
182
|
Chris@26
|
183 /* Conversion of realtime to a double precision floating point value */
|
Chris@26
|
184 /* ...in Python called by e.g. float(realtime) */
|
Chris@26
|
185 static PyObject *
|
Chris@26
|
186 RealTime_float(PyObject *s)
|
Chris@26
|
187 {
|
Chris@26
|
188 double drt = ((double) ((RealTimeObject*)s)->rt->sec +
|
Chris@39
|
189 (double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
|
Chris@39
|
190 return PyFloat_FromDouble(drt);
|
Chris@26
|
191 }
|
Chris@26
|
192
|
Chris@26
|
193
|
Chris@26
|
194 /* Type object's (RealTime) methods table */
|
Chris@26
|
195 static PyMethodDef RealTime_methods[] =
|
Chris@26
|
196 {
|
Chris@124
|
197 {"values", (PyCFunction)RealTime_values, METH_NOARGS,
|
Chris@26
|
198 PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
|
Chris@26
|
199
|
Chris@124
|
200 {"to_string", (PyCFunction)RealTime_toString, METH_NOARGS,
|
Chris@82
|
201 PyDoc_STR("to_string() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
|
Chris@26
|
202
|
Chris@82
|
203 {"to_frame", (PyCFunction)RealTime_toFrame, METH_VARARGS,
|
Chris@82
|
204 PyDoc_STR("to_frame(samplerate) -> Sample count for given sample rate.")},
|
Chris@26
|
205
|
Chris@82
|
206 {"to_float", (PyCFunction)RealTime_float, METH_NOARGS,
|
Chris@82
|
207 PyDoc_STR("to_float() -> Floating point representation.")},
|
Chris@39
|
208
|
Chris@39
|
209 {NULL, NULL} /* sentinel */
|
Chris@26
|
210 };
|
Chris@26
|
211
|
Chris@26
|
212
|
Chris@26
|
213 /* Methods implementing protocols */
|
Chris@26
|
214 // these functions are called by the interpreter
|
Chris@26
|
215
|
Chris@26
|
216 /* Object Protocol */
|
Chris@26
|
217
|
Chris@26
|
218 static int
|
Chris@26
|
219 RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
|
Chris@26
|
220 {
|
Chris@124
|
221 if (!string(name).compare("sec")) {
|
Chris@124
|
222 self->rt->sec = (int) PyInt_AS_LONG(value);
|
Chris@39
|
223 return 0;
|
Chris@26
|
224 }
|
Chris@26
|
225
|
Chris@124
|
226 if (!string(name).compare("nsec")) {
|
Chris@124
|
227 self->rt->nsec = (int) PyInt_AS_LONG(value);
|
Chris@39
|
228 return 0;
|
Chris@26
|
229 }
|
Chris@26
|
230
|
Chris@26
|
231 return -1;
|
Chris@26
|
232 }
|
Chris@26
|
233
|
Chris@26
|
234 static PyObject *
|
Chris@112
|
235 RealTime_getattro(RealTimeObject *self, PyObject *nameobj)
|
Chris@26
|
236 {
|
Chris@112
|
237 string name;
|
Chris@112
|
238 #if PY_MAJOR_VERSION < 3
|
Chris@112
|
239 name = PyString_AsString(nameobj);
|
Chris@112
|
240 #else
|
Chris@112
|
241 name = PyBytes_AsString(PyUnicode_AsUTF8String(nameobj));
|
Chris@112
|
242 #endif
|
Chris@112
|
243
|
Chris@26
|
244 if ( !string(name).compare("sec") ) {
|
Chris@39
|
245 return PyInt_FromSsize_t(
|
Chris@39
|
246 (Py_ssize_t) self->rt->sec);
|
Chris@26
|
247 }
|
Chris@26
|
248
|
Chris@26
|
249 if ( !string(name).compare("nsec") ) {
|
Chris@39
|
250 return PyInt_FromSsize_t(
|
Chris@39
|
251 (Py_ssize_t) self->rt->nsec);
|
Chris@26
|
252 }
|
Chris@26
|
253
|
Chris@112
|
254 return PyObject_GenericGetAttr((PyObject *)self, nameobj);
|
Chris@26
|
255 }
|
Chris@26
|
256
|
Chris@112
|
257 static PyObject *
|
Chris@112
|
258 RealTime_richcompare(PyObject *self, PyObject *other, int op)
|
Chris@73
|
259 {
|
Chris@73
|
260 if (!PyRealTime_Check(self) || !PyRealTime_Check(other)) {
|
Chris@73
|
261 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
|
Chris@112
|
262 return Py_False;
|
Chris@73
|
263 }
|
Chris@73
|
264
|
Chris@113
|
265 RealTime *ap = PyRealTime_AS_REALTIME(self);
|
Chris@113
|
266 RealTime *bp = PyRealTime_AS_REALTIME(other);
|
Chris@113
|
267
|
Chris@113
|
268 if (!ap || !bp) return Py_False;
|
Chris@113
|
269 const RealTime &a = *ap;
|
Chris@113
|
270 const RealTime &b = *bp;
|
Chris@73
|
271
|
Chris@116
|
272 // cerr << "a = " << a << ", b = " << b << ", op = " << op << endl;
|
Chris@116
|
273
|
Chris@116
|
274 PyObject *result = Py_False;
|
Chris@116
|
275
|
Chris@112
|
276 if (op == Py_LT) {
|
Chris@116
|
277 result = (a < b) ? Py_True : Py_False;
|
Chris@112
|
278 } else if (op == Py_LE) {
|
Chris@116
|
279 result = (a <= b) ? Py_True : Py_False;
|
Chris@112
|
280 } else if (op == Py_EQ) {
|
Chris@116
|
281 result = (a == b) ? Py_True : Py_False;
|
Chris@112
|
282 } else if (op == Py_NE) {
|
Chris@116
|
283 result = (a != b) ? Py_True : Py_False;
|
Chris@112
|
284 } else if (op == Py_GT) {
|
Chris@116
|
285 result = (a > b) ? Py_True : Py_False;
|
Chris@112
|
286 } else if (op == Py_GE) {
|
Chris@116
|
287 result = (a >= b) ? Py_True : Py_False;
|
Chris@112
|
288 }
|
Chris@116
|
289
|
Chris@116
|
290 // cerr << "returning: " << (result == Py_True ? "true" : "false") << endl;
|
Chris@116
|
291
|
Chris@134
|
292 Py_INCREF(result);
|
Chris@116
|
293 return result;
|
Chris@73
|
294 }
|
Chris@73
|
295
|
Chris@26
|
296 /* String representation called by e.g. str(realtime), print realtime*/
|
Chris@26
|
297 static PyObject *
|
Chris@26
|
298 RealTime_repr(PyObject *self)
|
Chris@26
|
299 {
|
Chris@26
|
300 return Py_BuildValue("s",
|
Chris@39
|
301 ((RealTimeObject*)self)->rt->toString().c_str());
|
Chris@26
|
302 }
|
Chris@26
|
303
|
Chris@26
|
304
|
Chris@26
|
305 /* Number Protocol */
|
Chris@26
|
306 /// TODO: implement all methods available in Vamp::RealTime() objects
|
Chris@26
|
307
|
Chris@26
|
308 static PyObject *
|
Chris@26
|
309 RealTime_add(PyObject *s, PyObject *w)
|
Chris@26
|
310 {
|
Chris@124
|
311 RealTimeObject *result = PyObject_New(RealTimeObject, &RealTime_Type);
|
Chris@26
|
312 if (result == NULL) return NULL;
|
Chris@124
|
313 PyObject_Init((PyObject *)result, &RealTime_Type);
|
Chris@26
|
314
|
Chris@26
|
315 result->rt = new RealTime(
|
Chris@39
|
316 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
|
Chris@26
|
317 return (PyObject*)result;
|
Chris@26
|
318 }
|
Chris@26
|
319
|
Chris@26
|
320 static PyObject *
|
Chris@26
|
321 RealTime_subtract(PyObject *s, PyObject *w)
|
Chris@26
|
322 {
|
Chris@124
|
323 RealTimeObject *result = PyObject_New(RealTimeObject, &RealTime_Type);
|
Chris@26
|
324 if (result == NULL) return NULL;
|
Chris@124
|
325 PyObject_Init((PyObject *)result, &RealTime_Type);
|
Chris@26
|
326
|
Chris@26
|
327 result->rt = new RealTime(
|
Chris@39
|
328 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
|
Chris@26
|
329 return (PyObject*)result;
|
Chris@26
|
330 }
|
Chris@26
|
331
|
Chris@26
|
332 static PyNumberMethods realtime_as_number =
|
Chris@26
|
333 {
|
Chris@112
|
334 (binaryfunc)RealTime_add, /*nb_add*/
|
Chris@112
|
335 (binaryfunc)RealTime_subtract, /*nb_subtract*/
|
Chris@39
|
336 0, /*nb_multiply*/
|
Chris@112
|
337 #if (PY_MAJOR_VERSION < 3)
|
Chris@39
|
338 0, /*nb_divide*/
|
Chris@112
|
339 #endif
|
Chris@39
|
340 0, /*nb_remainder*/
|
Chris@39
|
341 0, /*nb_divmod*/
|
Chris@39
|
342 0, /*nb_power*/
|
Chris@39
|
343 0, /*nb_neg*/
|
Chris@39
|
344 0, /*nb_pos*/
|
Chris@39
|
345 0, /*(unaryfunc)array_abs,*/
|
Chris@39
|
346 0, /*nb_nonzero*/
|
Chris@39
|
347 0, /*nb_invert*/
|
Chris@39
|
348 0, /*nb_lshift*/
|
Chris@39
|
349 0, /*nb_rshift*/
|
Chris@39
|
350 0, /*nb_and*/
|
Chris@39
|
351 0, /*nb_xor*/
|
Chris@39
|
352 0, /*nb_or*/
|
Chris@112
|
353 #if (PY_MAJOR_VERSION < 3)
|
Chris@26
|
354 0, /*nb_coerce*/
|
Chris@112
|
355 #endif
|
Chris@39
|
356 0, /*nb_int*/
|
Chris@39
|
357 0, /*nb_long*/
|
Chris@26
|
358 (unaryfunc)RealTime_float,/*nb_float*/
|
Chris@26
|
359 };
|
Chris@26
|
360
|
Chris@26
|
361 /* REAL-TIME TYPE OBJECT */
|
Chris@26
|
362
|
Chris@26
|
363 /* Doc:: 10.3 Type Objects */ /* static */
|
Chris@26
|
364 PyTypeObject RealTime_Type =
|
Chris@26
|
365 {
|
Chris@112
|
366 PyVarObject_HEAD_INIT(NULL, 0)
|
Chris@124
|
367 "vampyhost.RealTime", /*tp_name*/
|
Chris@39
|
368 sizeof(RealTimeObject), /*tp_basicsize*/
|
Chris@39
|
369 0, /*tp_itemsize*/
|
Chris@39
|
370 /* methods */
|
Chris@26
|
371 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
|
Chris@39
|
372 0, /*tp_print*/
|
Chris@112
|
373 0, /*tp_getattr*/
|
Chris@26
|
374 (setattrfunc)RealTime_setattr, /*tp_setattr*/
|
Chris@112
|
375 0, /*tp_compare*/
|
Chris@39
|
376 RealTime_repr, /*tp_repr*/
|
Chris@39
|
377 &realtime_as_number, /*tp_as_number*/
|
Chris@39
|
378 0, /*tp_as_sequence*/
|
Chris@39
|
379 0, /*tp_as_mapping*/
|
Chris@39
|
380 0, /*tp_hash*/
|
Chris@39
|
381 0, /*tp_call*/
|
Chris@26
|
382 0, /*tp_str*/
|
Chris@112
|
383 (getattrofunc)RealTime_getattro, /*tp_getattro*/
|
Chris@26
|
384 0, /*tp_setattro*/
|
Chris@26
|
385 0, /*tp_as_buffer*/
|
Chris@26
|
386 Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
Chris@39
|
387 "RealTime object, used for Vamp plugin timestamps.", /*tp_doc*/
|
Chris@26
|
388 0, /*tp_traverse*/
|
Chris@26
|
389 0, /*tp_clear*/
|
Chris@112
|
390 (richcmpfunc)RealTime_richcompare, /*tp_richcompare*/
|
Chris@26
|
391 0, /*tp_weaklistoffset*/
|
Chris@26
|
392 0, /*tp_iter*/
|
Chris@26
|
393 0, /*tp_iternext*/
|
Chris@26
|
394 RealTime_methods, /*tp_methods*/ //TypeObject Methods
|
Chris@26
|
395 0, /*tp_members*/
|
Chris@26
|
396 0, /*tp_getset*/
|
Chris@26
|
397 0, /*tp_base*/
|
Chris@26
|
398 0, /*tp_dict*/
|
Chris@26
|
399 0, /*tp_descr_get*/
|
Chris@26
|
400 0, /*tp_descr_set*/
|
Chris@26
|
401 0, /*tp_dictoffset*/
|
Chris@26
|
402 0, /*tp_init*/
|
Chris@124
|
403 0, /*tp_alloc*/
|
Chris@26
|
404 RealTime_new, /*tp_new*/
|
Chris@124
|
405 0, /*tp_free*/
|
Chris@26
|
406 0, /*tp_is_gc*/
|
Chris@26
|
407 };
|
Chris@26
|
408
|
Chris@26
|
409
|
Chris@26
|
410
|
Chris@26
|
411 /* PyRealTime C++ API */
|
Chris@26
|
412
|
Chris@26
|
413 /*PyRealTime from RealTime*/
|
Chris@26
|
414 PyObject*
|
Chris@26
|
415 PyRealTime_FromRealTime(const Vamp::RealTime& rt) {
|
Chris@26
|
416
|
Chris@26
|
417 RealTimeObject *self =
|
Chris@39
|
418 PyObject_New(RealTimeObject, &RealTime_Type);
|
Chris@26
|
419 if (self == NULL) return NULL;
|
Chris@26
|
420
|
Chris@26
|
421 self->rt = new RealTime(rt);
|
Chris@26
|
422 return (PyObject*) self;
|
Chris@26
|
423 }
|
Chris@26
|
424
|
Chris@26
|
425 /*RealTime* from PyRealTime*/
|
Chris@26
|
426 const Vamp::RealTime*
|
Chris@26
|
427 PyRealTime_AsRealTime (PyObject *self) {
|
Chris@26
|
428
|
Chris@26
|
429 RealTimeObject *s = (RealTimeObject*) self;
|
Chris@26
|
430
|
Chris@26
|
431 if (!PyRealTime_Check(s)) {
|
Chris@39
|
432 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
|
Chris@39
|
433 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
|
Chris@113
|
434 return NULL;
|
Chris@113
|
435 }
|
Chris@26
|
436 return s->rt;
|
Chris@26
|
437 };
|
Chris@26
|
438
|