fazekasgy@31
|
1 #include <Python.h>
|
fazekasgy@31
|
2 #include "PyRealTime.h"
|
fazekasgy@31
|
3 #include "vamp-sdk/Plugin.h"
|
fazekasgy@31
|
4 #include <string>
|
fazekasgy@31
|
5
|
fazekasgy@31
|
6 using namespace std;
|
fazekasgy@31
|
7 using namespace Vamp;
|
fazekasgy@31
|
8 using Vamp::Plugin;
|
fazekasgy@31
|
9 using Vamp::RealTime;
|
fazekasgy@31
|
10
|
fazekasgy@31
|
11
|
fazekasgy@31
|
12 /* CONSTRUCTOR: New RealTime object from sec and nsec */
|
fazekasgy@31
|
13 static PyObject*
|
fazekasgy@31
|
14 RealTime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
fazekasgy@31
|
15 {
|
fazekasgy@31
|
16 unsigned int sec = 0;
|
fazekasgy@31
|
17 unsigned int nsec = 0;
|
fazekasgy@31
|
18 double unary = 0;
|
fazekasgy@31
|
19 const char *fmt = NULL;
|
fazekasgy@31
|
20
|
fazekasgy@31
|
21 if (
|
fazekasgy@31
|
22 /// new RealTime from ('format',float) e.g. ('seconds',2.34123)
|
fazekasgy@31
|
23 !PyArg_ParseTuple(args, "|sd:RealTime.new ",
|
fazekasgy@31
|
24 (const char *) &fmt,
|
fazekasgy@31
|
25 (double *) &unary) &&
|
fazekasgy@31
|
26
|
fazekasgy@31
|
27 /// new RealTime from (sec{int},nsec{int}) e.g. (2,34)
|
fazekasgy@31
|
28 !PyArg_ParseTuple(args, "|II:RealTime.new ",
|
fazekasgy@31
|
29 (unsigned int*) &sec,
|
fazekasgy@31
|
30 (unsigned int*) &nsec)
|
fazekasgy@31
|
31
|
fazekasgy@31
|
32 ) {
|
fazekasgy@31
|
33 PyErr_SetString(PyExc_TypeError,
|
fazekasgy@31
|
34 "RealTime initialised with wrong arguments.");
|
fazekasgy@31
|
35 return NULL;
|
fazekasgy@31
|
36 }
|
fazekasgy@31
|
37
|
fazekasgy@31
|
38 // PyErr_Clear();
|
fazekasgy@31
|
39
|
fazekasgy@31
|
40 // RealTimeObject *self = PyObject_New(RealTimeObject, &RealTime_Type);
|
fazekasgy@31
|
41 RealTimeObject *self = (RealTimeObject*)type->tp_alloc(type, 0);
|
fazekasgy@31
|
42
|
fazekasgy@31
|
43 if (self == NULL) return NULL;
|
fazekasgy@31
|
44
|
fazekasgy@31
|
45 self->rt = NULL;
|
fazekasgy@31
|
46
|
fazekasgy@31
|
47 if (sec == 0 && nsec == 0 && fmt == 0)
|
cannam@34
|
48 self->rt = new RealTime();
|
fazekasgy@31
|
49 else if (fmt == 0)
|
cannam@34
|
50 self->rt = new RealTime(sec,nsec);
|
fazekasgy@31
|
51 else {
|
fazekasgy@31
|
52 /// new RealTime from seconds or milliseconds: i.e. >>>RealTime('seconds',12.3)
|
fazekasgy@31
|
53 if (!string(fmt).compare("float") ||
|
fazekasgy@31
|
54 !string(fmt).compare("seconds"))
|
cannam@34
|
55 self->rt = new RealTime(
|
fazekasgy@31
|
56 RealTime::fromSeconds((double) unary));
|
fazekasgy@31
|
57
|
fazekasgy@31
|
58 if (!string(fmt).compare("milliseconds")) {
|
cannam@34
|
59 self->rt = new RealTime(
|
fazekasgy@31
|
60 RealTime::fromSeconds((double) unary / 1000.0)); }
|
fazekasgy@31
|
61 }
|
fazekasgy@31
|
62
|
fazekasgy@31
|
63 if (!self->rt) {
|
fazekasgy@31
|
64 PyErr_SetString(PyExc_TypeError,
|
fazekasgy@31
|
65 "RealTime initialised with wrong arguments.");
|
fazekasgy@31
|
66 return NULL;
|
fazekasgy@31
|
67 }
|
fazekasgy@31
|
68
|
fazekasgy@31
|
69 return (PyObject *) self;
|
fazekasgy@31
|
70 }
|
fazekasgy@31
|
71
|
fazekasgy@31
|
72 /* DESTRUCTOR: delete type object */
|
fazekasgy@31
|
73 static void
|
fazekasgy@31
|
74 RealTimeObject_dealloc(RealTimeObject *self)
|
fazekasgy@31
|
75 {
|
fazekasgy@31
|
76 if (self->rt) delete self->rt; //delete the C object
|
fazekasgy@31
|
77 PyObject_Del(self); //delete the Python object (original)
|
fazekasgy@31
|
78 /// this requires PyType_Ready() which fills ob_type
|
fazekasgy@31
|
79 // self->ob_type->tp_free((PyObject*)self);
|
fazekasgy@31
|
80 }
|
fazekasgy@31
|
81
|
fazekasgy@31
|
82 /* RealTime Object's Methods */
|
fazekasgy@31
|
83 //these are internals not exposed by the module but the object
|
fazekasgy@31
|
84
|
fazekasgy@31
|
85 /* Returns a Tuple containing sec and nsec values */
|
fazekasgy@31
|
86 static PyObject *
|
fazekasgy@31
|
87 RealTime_values(RealTimeObject *self)
|
fazekasgy@31
|
88 {
|
fazekasgy@31
|
89 return Py_BuildValue("(ii)",self->rt->sec,self->rt->nsec);
|
fazekasgy@31
|
90 }
|
fazekasgy@31
|
91
|
fazekasgy@31
|
92 /* Returns a Text representation */
|
fazekasgy@31
|
93 static PyObject *
|
fazekasgy@31
|
94 RealTime_toString(RealTimeObject *self, PyObject *args)
|
fazekasgy@31
|
95 {
|
fazekasgy@31
|
96 return Py_BuildValue("s",self->rt->toText().c_str());
|
fazekasgy@31
|
97 }
|
fazekasgy@31
|
98
|
fazekasgy@31
|
99 /* Frame representation */
|
fazekasgy@31
|
100 static PyObject *
|
fazekasgy@31
|
101 RealTime_toFrame(PyObject *self, PyObject *args)
|
fazekasgy@31
|
102 {
|
fazekasgy@31
|
103 unsigned int samplerate;
|
fazekasgy@31
|
104
|
fazekasgy@31
|
105 if ( !PyArg_ParseTuple(args, "I:realtime.toFrame object ",
|
fazekasgy@31
|
106 (unsigned int *) &samplerate )) {
|
fazekasgy@31
|
107 PyErr_SetString(PyExc_ValueError,"Integer Sample Rate Required.");
|
fazekasgy@31
|
108 return NULL;
|
fazekasgy@31
|
109 }
|
fazekasgy@31
|
110
|
fazekasgy@31
|
111 return Py_BuildValue("k",
|
fazekasgy@31
|
112 RealTime::realTime2Frame(
|
fazekasgy@31
|
113 *(const RealTime*) ((RealTimeObject*)self)->rt,
|
fazekasgy@31
|
114 (unsigned int) samplerate));
|
fazekasgy@31
|
115 }
|
fazekasgy@31
|
116
|
fazekasgy@31
|
117 /* Conversion of realtime to a double precision floating point value */
|
fazekasgy@31
|
118 /* ...in Python called by e.g. float(realtime) */
|
fazekasgy@31
|
119 static PyObject *
|
fazekasgy@31
|
120 RealTime_float(PyObject *s)
|
fazekasgy@31
|
121 {
|
fazekasgy@31
|
122 double drt = ((double) ((RealTimeObject*)s)->rt->sec +
|
fazekasgy@31
|
123 (double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
|
fazekasgy@31
|
124 return PyFloat_FromDouble(drt);
|
fazekasgy@31
|
125 }
|
fazekasgy@31
|
126
|
fazekasgy@31
|
127
|
fazekasgy@31
|
128 /* Type object's (RealTime) methods table */
|
fazekasgy@31
|
129 static PyMethodDef RealTime_methods[] =
|
fazekasgy@31
|
130 {
|
fazekasgy@31
|
131 {"values", (PyCFunction)RealTime_values, METH_NOARGS,
|
fazekasgy@31
|
132 PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
|
fazekasgy@31
|
133
|
fazekasgy@31
|
134 {"toString", (PyCFunction)RealTime_toString, METH_NOARGS,
|
fazekasgy@31
|
135 PyDoc_STR("toString() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
|
fazekasgy@31
|
136
|
fazekasgy@31
|
137 {"toFrame", (PyCFunction)RealTime_toFrame, METH_VARARGS,
|
fazekasgy@31
|
138 PyDoc_STR("toFrame(samplerate) -> Sample count for given sample rate.")},
|
fazekasgy@31
|
139
|
fazekasgy@31
|
140 {"toFloat", (PyCFunction)RealTime_float, METH_NOARGS,
|
fazekasgy@31
|
141 PyDoc_STR("toFloat() -> Floating point representation.")},
|
fazekasgy@31
|
142
|
fazekasgy@31
|
143 {NULL, NULL} /* sentinel */
|
fazekasgy@31
|
144 };
|
fazekasgy@31
|
145
|
fazekasgy@31
|
146
|
fazekasgy@31
|
147 /* Methods implementing protocols */
|
fazekasgy@31
|
148 // these functions are called by the interpreter
|
fazekasgy@31
|
149
|
fazekasgy@31
|
150 /* Object Protocol */
|
fazekasgy@31
|
151
|
fazekasgy@31
|
152 static int
|
fazekasgy@31
|
153 RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
|
fazekasgy@31
|
154 {
|
fazekasgy@31
|
155
|
fazekasgy@31
|
156 if ( !string(name).compare("sec")) {
|
fazekasgy@31
|
157 self->rt->sec= (int) PyInt_AS_LONG(value);
|
fazekasgy@31
|
158 return 0;
|
fazekasgy@31
|
159 }
|
fazekasgy@31
|
160
|
fazekasgy@31
|
161 if ( !string(name).compare("nsec")) {
|
fazekasgy@31
|
162 self->rt->nsec= (int) PyInt_AS_LONG(value);
|
fazekasgy@31
|
163 return 0;
|
fazekasgy@31
|
164 }
|
fazekasgy@31
|
165
|
fazekasgy@31
|
166 return -1;
|
fazekasgy@31
|
167 }
|
fazekasgy@31
|
168
|
fazekasgy@31
|
169 static PyObject *
|
fazekasgy@31
|
170 RealTime_getattr(RealTimeObject *self, char *name)
|
fazekasgy@31
|
171 {
|
fazekasgy@31
|
172
|
fazekasgy@31
|
173 if ( !string(name).compare("sec") ) {
|
fazekasgy@31
|
174 return PyInt_FromSsize_t(
|
fazekasgy@31
|
175 (Py_ssize_t) self->rt->sec);
|
fazekasgy@31
|
176 }
|
fazekasgy@31
|
177
|
fazekasgy@31
|
178 if ( !string(name).compare("nsec") ) {
|
fazekasgy@31
|
179 return PyInt_FromSsize_t(
|
fazekasgy@31
|
180 (Py_ssize_t) self->rt->nsec);
|
fazekasgy@31
|
181 }
|
fazekasgy@31
|
182
|
fazekasgy@31
|
183 return Py_FindMethod(RealTime_methods,
|
fazekasgy@31
|
184 (PyObject *)self, name);
|
fazekasgy@31
|
185 }
|
fazekasgy@31
|
186
|
fazekasgy@31
|
187 /* String representation called by e.g. str(realtime), print realtime*/
|
fazekasgy@31
|
188 static PyObject *
|
fazekasgy@31
|
189 RealTime_repr(PyObject *self)
|
fazekasgy@31
|
190 {
|
fazekasgy@31
|
191 return Py_BuildValue("s",
|
fazekasgy@31
|
192 ((RealTimeObject*)self)->rt->toString().c_str());
|
fazekasgy@31
|
193 }
|
fazekasgy@31
|
194
|
fazekasgy@31
|
195
|
fazekasgy@31
|
196 /* Number Protocol */
|
fazekasgy@31
|
197 /// Only add and substract make sense, or what about the
|
fazekasgy@31
|
198 /// square root of Monday morning?
|
fazekasgy@31
|
199 /// Divide by integer maybe for durations?
|
fazekasgy@31
|
200
|
fazekasgy@31
|
201 static PyObject *
|
fazekasgy@31
|
202 RealTime_add(PyObject *s, PyObject *w)
|
fazekasgy@31
|
203 {
|
fazekasgy@31
|
204 RealTimeObject *result =
|
fazekasgy@31
|
205 PyObject_New(RealTimeObject, &RealTime_Type);
|
fazekasgy@31
|
206 if (result == NULL) return NULL;
|
fazekasgy@31
|
207
|
cannam@34
|
208 result->rt = new RealTime(
|
fazekasgy@31
|
209 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
|
fazekasgy@31
|
210 return (PyObject*)result;
|
fazekasgy@31
|
211 }
|
fazekasgy@31
|
212
|
fazekasgy@31
|
213 static PyObject *
|
fazekasgy@31
|
214 RealTime_subtract(PyObject *s, PyObject *w)
|
fazekasgy@31
|
215 {
|
fazekasgy@31
|
216 RealTimeObject *result =
|
fazekasgy@31
|
217 PyObject_New(RealTimeObject, &RealTime_Type);
|
fazekasgy@31
|
218 if (result == NULL) return NULL;
|
fazekasgy@31
|
219
|
cannam@34
|
220 result->rt = new RealTime(
|
fazekasgy@31
|
221 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
|
fazekasgy@31
|
222 return (PyObject*)result;
|
fazekasgy@31
|
223 }
|
fazekasgy@31
|
224
|
fazekasgy@31
|
225 static PyNumberMethods realtime_as_number =
|
fazekasgy@31
|
226 {
|
fazekasgy@31
|
227 RealTime_add, /*nb_add*/
|
fazekasgy@31
|
228 RealTime_subtract, /*nb_subtract*/
|
fazekasgy@31
|
229 0, /*nb_multiply*/
|
fazekasgy@31
|
230 0, /*nb_divide*/
|
fazekasgy@31
|
231 0, /*nb_remainder*/
|
fazekasgy@31
|
232 0, /*nb_divmod*/
|
fazekasgy@31
|
233 0, /*nb_power*/
|
fazekasgy@31
|
234 0, /*nb_neg*/
|
fazekasgy@31
|
235 0, /*nb_pos*/
|
fazekasgy@31
|
236 0, /*(unaryfunc)array_abs,*/
|
fazekasgy@31
|
237 0, /*nb_nonzero*/
|
fazekasgy@31
|
238 0, /*nb_invert*/
|
fazekasgy@31
|
239 0, /*nb_lshift*/
|
fazekasgy@31
|
240 0, /*nb_rshift*/
|
fazekasgy@31
|
241 0, /*nb_and*/
|
fazekasgy@31
|
242 0, /*nb_xor*/
|
fazekasgy@31
|
243 0, /*nb_or*/
|
fazekasgy@31
|
244 0, /*nb_coerce*/
|
fazekasgy@31
|
245 0, /*nb_int*/
|
fazekasgy@31
|
246 0, /*nb_long*/
|
fazekasgy@31
|
247 (unaryfunc)RealTime_float,/*nb_float*/
|
fazekasgy@31
|
248 0, /*nb_oct*/
|
fazekasgy@31
|
249 0, /*nb_hex*/
|
fazekasgy@31
|
250 };
|
fazekasgy@31
|
251
|
fazekasgy@31
|
252 /* REAL-TIME TYPE OBJECT */
|
fazekasgy@31
|
253
|
fazekasgy@31
|
254 #define RealTime_alloc PyType_GenericAlloc
|
fazekasgy@31
|
255 #define RealTime_free PyObject_Del
|
fazekasgy@31
|
256
|
fazekasgy@31
|
257 /* Doc:: 10.3 Type Objects */ /* static */
|
fazekasgy@31
|
258 PyTypeObject RealTime_Type =
|
fazekasgy@31
|
259 {
|
fazekasgy@31
|
260 PyObject_HEAD_INIT(NULL)
|
fazekasgy@31
|
261 0, /*ob_size*/
|
fazekasgy@31
|
262 "vampy.RealTime", /*tp_name*/
|
fazekasgy@31
|
263 sizeof(RealTimeObject), /*tp_basicsize*/
|
fazekasgy@31
|
264 0,//sizeof(RealTime), /*tp_itemsize*/
|
fazekasgy@31
|
265 /* methods */
|
fazekasgy@31
|
266 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
|
fazekasgy@31
|
267 0, /*tp_print*/
|
fazekasgy@31
|
268 (getattrfunc)RealTime_getattr, /*tp_getattr*/
|
fazekasgy@31
|
269 (setattrfunc)RealTime_setattr, /*tp_setattr*/
|
fazekasgy@31
|
270 0, /*tp_compare*/
|
fazekasgy@31
|
271 RealTime_repr, /*tp_repr*/
|
fazekasgy@31
|
272 &realtime_as_number, /*tp_as_number*/
|
fazekasgy@31
|
273 0, /*tp_as_sequence*/
|
fazekasgy@31
|
274 0, /*tp_as_mapping*/
|
fazekasgy@31
|
275 0, /*tp_hash*/
|
fazekasgy@31
|
276 0,//(ternaryfunc)RealTime_new, /*tp_call*/
|
fazekasgy@31
|
277 0, /*tp_str*/
|
fazekasgy@31
|
278 0, /*tp_getattro*/
|
fazekasgy@31
|
279 0, /*tp_setattro*/
|
fazekasgy@31
|
280 0, /*tp_as_buffer*/
|
fazekasgy@31
|
281 Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
fazekasgy@31
|
282 "RealTime Object", /*tp_doc*/
|
fazekasgy@31
|
283 0, /*tp_traverse*/
|
fazekasgy@31
|
284 0, /*tp_clear*/
|
fazekasgy@31
|
285 0, /*tp_richcompare*/
|
fazekasgy@31
|
286 0, /*tp_weaklistoffset*/
|
fazekasgy@31
|
287 0, /*tp_iter*/
|
fazekasgy@31
|
288 0, /*tp_iternext*/
|
fazekasgy@31
|
289 RealTime_methods, /*tp_methods*/ //TypeObject Methods
|
fazekasgy@31
|
290 0, /*tp_members*/
|
fazekasgy@31
|
291 0, /*tp_getset*/
|
fazekasgy@31
|
292 0, /*tp_base*/
|
fazekasgy@31
|
293 0, /*tp_dict*/
|
fazekasgy@31
|
294 0, /*tp_descr_get*/
|
fazekasgy@31
|
295 0, /*tp_descr_set*/
|
fazekasgy@31
|
296 0, /*tp_dictoffset*/
|
fazekasgy@31
|
297 0, /*tp_init*/
|
fazekasgy@31
|
298 RealTime_alloc, /*tp_alloc*/
|
fazekasgy@31
|
299 RealTime_new, /*tp_new*/
|
fazekasgy@31
|
300 RealTime_free, /*tp_free*/
|
fazekasgy@31
|
301 0, /*tp_is_gc*/
|
fazekasgy@31
|
302 };
|
fazekasgy@31
|
303
|
fazekasgy@31
|
304
|
fazekasgy@31
|
305
|
fazekasgy@31
|
306 /* PyRealTime C++ API */
|
fazekasgy@31
|
307
|
fazekasgy@31
|
308 /*PyRealTime from RealTime pointer
|
fazekasgy@31
|
309 PyObject*
|
fazekasgy@31
|
310 PyRealTime_FromRealTime(Vamp::RealTime *rt) {
|
fazekasgy@31
|
311
|
fazekasgy@31
|
312 RealTimeObject *self =
|
fazekasgy@31
|
313 PyObject_New(RealTimeObject, &RealTime_Type);
|
fazekasgy@31
|
314 if (self == NULL) return NULL;
|
fazekasgy@31
|
315
|
cannam@34
|
316 self->rt = new RealTime(*rt);
|
fazekasgy@31
|
317 return (PyObject*) self;
|
fazekasgy@31
|
318 }*/
|
fazekasgy@31
|
319
|
fazekasgy@31
|
320
|
fazekasgy@31
|
321 /*PyRealTime from RealTime*/
|
fazekasgy@31
|
322 PyObject*
|
fazekasgy@31
|
323 PyRealTime_FromRealTime(Vamp::RealTime& rt) {
|
fazekasgy@31
|
324
|
fazekasgy@31
|
325 RealTimeObject *self =
|
fazekasgy@31
|
326 PyObject_New(RealTimeObject, &RealTime_Type);
|
fazekasgy@31
|
327 if (self == NULL) return NULL;
|
fazekasgy@31
|
328
|
cannam@34
|
329 self->rt = new RealTime(rt);
|
fazekasgy@31
|
330 return (PyObject*) self;
|
fazekasgy@31
|
331 }
|
fazekasgy@31
|
332
|
fazekasgy@31
|
333 /*RealTime* from PyRealTime*/
|
cannam@34
|
334 const Vamp::RealTime*
|
fazekasgy@31
|
335 PyRealTime_AsRealTime (PyObject *self) {
|
fazekasgy@31
|
336
|
fazekasgy@31
|
337 RealTimeObject *s = (RealTimeObject*) self;
|
fazekasgy@31
|
338
|
fazekasgy@31
|
339 if (!PyRealTime_Check(s)) {
|
fazekasgy@31
|
340 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
|
fazekasgy@31
|
341 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
|
fazekasgy@31
|
342 return NULL; }
|
fazekasgy@31
|
343 return s->rt;
|
fazekasgy@31
|
344 };
|
fazekasgy@31
|
345
|