comparison host/pyRealTime.cpp @ 11:4610f2b8477d

added pyRealTime object impl to host
author fazekasgy
date Mon, 16 Jun 2008 09:44:48 +0000
parents
children
comparison
equal deleted inserted replaced
10:8e9fbe4dc94d 11:4610f2b8477d
1 /*
2
3 This module exposes a Type Object wrapping VAMP::RealTime
4 together with module level functions to create
5 new pyRealTime objects from frame count, samplerate or sec,nsec tuples.
6
7 A small API is provided for the C/C++ programmer and relevant
8 functions are exposed to Python.
9
10 TODO: implement number protocol (i.e. wrap arithmetic operators)
11 partly done
12
13 */
14
15 #include <Python.h>
16 #include <pyRealTime.h>
17 #include "vamp-sdk/Plugin.h"
18 #include <string>
19
20 using namespace std;
21 using namespace Vamp;
22
23 using Vamp::Plugin;
24 using Vamp::RealTime;
25
26 /* REAL-TIME TYPE OBJECT */
27
28
29 /* Documentation for our new module */
30 PyDoc_STRVAR(module_doc,
31 "This module is a thin wrapper around VAMP::RealTime.");
32
33
34 /* RealTime Object's Methods */
35 //Note: these are internals, not exposed by the module but the object
36
37 /* Returns a Tuple containing sec and nsec values */
38 static PyObject *
39 RealTime_values(RealTimeObject *self)
40 {
41 return Py_BuildValue("(ii)",
42 self->rt->sec,self->rt->nsec);
43 }
44
45 /* Returns a Text representation */
46 static PyObject *
47 RealTime_toText(RealTimeObject *self, PyObject *args)
48 {
49 return Py_BuildValue("s",
50 self->rt->toText().c_str());
51 }
52
53 /* String representation called by e.g. str(realtime), print realtime*/
54 static PyObject *
55 RealTime_repr(PyObject *self)
56 {
57 return Py_BuildValue("s",
58 ((RealTimeObject*)self)->rt->toString().c_str());
59 }
60
61
62 /* Frame representation */
63 static PyObject *
64 RealTime_toFrame(PyObject *self, PyObject *args)
65 {
66 unsigned int samplerate;
67
68 if ( !PyArg_ParseTuple(args, "I:realtime.toFrame object ",
69 (unsigned int *) &samplerate )) {
70 PyErr_SetString(PyExc_ValueError,
71 "Sample Rate Required.");
72 return NULL;
73 }
74
75 return Py_BuildValue("k",
76 RealTime::realTime2Frame(
77 *(const RealTime*) ((RealTimeObject*)self)->rt,
78 (unsigned int) samplerate));
79 }
80
81 /* Conversion of realtime to a double precision floating point value */
82 /* ...in Python called by e.g. float(realtime) */
83 static PyObject *
84 RealTime_float(PyObject *s)
85 {
86 double drt = ((double) ((RealTimeObject*)s)->rt->sec +
87 (double)((double) ((RealTimeObject*)s)->rt->nsec)/1000000000);
88 return PyFloat_FromDouble(drt);
89 }
90
91 /* test */
92 static PyObject *
93 RealTime_test(PyObject *self)
94 {
95
96 long frame = 100;
97 unsigned int sampleRate = 22050;
98
99 const RealTime t = RealTime::frame2RealTime(frame,sampleRate);
100 long back = RealTime::realTime2Frame(t,sampleRate);
101 cerr << "Reverse Conversion: " << back << endl;
102
103 return Py_BuildValue("s",
104 ((RealTimeObject*)self)->rt->toString().c_str());
105 }
106
107
108 /* Type object's (RealTime) methods table */
109 static PyMethodDef RealTime_methods[] = {
110
111 {"toText", (PyCFunction)RealTime_toText, METH_NOARGS,
112 PyDoc_STR("toText() -> Return a user-readable string to the nearest millisecond in a form like HH:MM:SS.mmm")},
113
114 {"values", (PyCFunction)RealTime_values, METH_NOARGS,
115 PyDoc_STR("values() -> Tuple of sec,nsec representation.")},
116
117 {"toFrame", (PyCFunction)RealTime_toFrame, METH_VARARGS,
118 PyDoc_STR("frame(samplerate) -> Sample count for given sample rate.")},
119
120 {"toFloat", (PyCFunction)RealTime_float, METH_NOARGS,
121 PyDoc_STR("float() -> Floating point representation.")},
122
123 {"test", (PyCFunction)RealTime_test, METH_VARARGS,
124 PyDoc_STR("test() -> .")},
125
126 {NULL, NULL} /* sentinel */
127 };
128
129
130
131 /* Function to set basic attributes */
132 static int
133 RealTime_setattr(RealTimeObject *self, char *name, PyObject *value)
134 {
135
136 if ( !string(name).compare("sec")) {
137 self->rt->sec= (int) PyInt_AS_LONG(value);
138 return 0;
139 }
140
141 if ( !string(name).compare("nsec")) {
142 self->rt->nsec= (int) PyInt_AS_LONG(value);
143 return 0;
144 }
145
146 return -1;
147 }
148
149 /* Function to get basic attributes */
150 static PyObject *
151 RealTime_getattr(RealTimeObject *self, char *name)
152 {
153
154 if ( !string(name).compare("sec") ) {
155 return PyInt_FromSsize_t(
156 (Py_ssize_t) self->rt->sec);
157 }
158
159 if ( !string(name).compare("nsec") ) {
160 return PyInt_FromSsize_t(
161 (Py_ssize_t) self->rt->nsec);
162 }
163
164 return Py_FindMethod(RealTime_methods,
165 (PyObject *)self, name);
166 }
167
168
169 /* DESTRUCTOR: delete type object */
170 static void
171 RealTimeObject_dealloc(RealTimeObject *self)
172 {
173 delete self->rt; //delete the C object
174 PyObject_Del(self); //delete the Python object
175 }
176
177 /* Number Protocol */
178
179
180 static PyObject *
181 RealTime_add(PyObject *s, PyObject *w)
182 {
183
184 RealTimeObject *result =
185 PyObject_New(RealTimeObject, &RealTime_Type);
186 if (result == NULL) return NULL;
187
188 result->rt = new RealTime::RealTime(
189 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
190 return (PyObject*)result;
191 }
192
193 static PyObject *
194 RealTime_subtract(PyObject *s, PyObject *w)
195 {
196
197 RealTimeObject *result =
198 PyObject_New(RealTimeObject, &RealTime_Type);
199 if (result == NULL) return NULL;
200
201 result->rt = new RealTime::RealTime(
202 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
203 return (PyObject*)result;
204 }
205
206
207 static PyNumberMethods realtime_as_number = {
208 RealTime_add, /*nb_add*/
209 RealTime_subtract, /*nb_subtract*/
210 0, /*nb_multiply*/
211 0, /*nb_divide*/
212 0, /*nb_remainder*/
213 0, /*nb_divmod*/
214 0, /*nb_power*/
215 0, /*nb_neg*/
216 0, /*nb_pos*/
217 0, /*(unaryfunc)array_abs,*/
218 0, /*nb_nonzero*/
219 0, /*nb_invert*/
220 0, /*nb_lshift*/
221 0, /*nb_rshift*/
222 0, /*nb_and*/
223 0, /*nb_xor*/
224 0, /*nb_or*/
225 0, /*nb_coerce*/
226 0, /*nb_int*/
227 0, /*nb_long*/
228 (unaryfunc)RealTime_float, /*nb_float*/
229 0, /*nb_oct*/
230 0, /*nb_hex*/
231 };
232
233 /* pyRealTime TypeObject */
234
235
236 /* Doc:: 10.3 Type Objects */
237 /* static */ PyTypeObject RealTime_Type = {
238 /* The ob_type field must be initialized in the module init function
239 * to be portable to Windows without using C++. */
240 PyObject_HEAD_INIT(NULL)
241 0, /*ob_size*/
242 "pyRealTime.realtime", /*tp_name*/
243 sizeof(RealTimeObject), /*tp_basicsize*/
244 sizeof(RealTime), /*tp_itemsize*/
245 /* methods */
246 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
247 0, /*tp_print*/
248 (getattrfunc)RealTime_getattr, /*tp_getattr*/
249 (setattrfunc)RealTime_setattr, /*tp_setattr*/
250 0, /*tp_compare*/
251 RealTime_repr, /*tp_repr*/
252 &realtime_as_number, /*tp_as_number*/
253 0, /*tp_as_sequence*/
254 0, /*tp_as_mapping*/
255 0, /*tp_hash*/
256 0,//(ternaryfunc)RealTime_new, /*tp_call*/
257 0, /*tp_str*/
258 0, /*tp_getattro*/
259 0, /*tp_setattro*/
260 0, /*tp_as_buffer*/
261 Py_TPFLAGS_DEFAULT, /*tp_flags*/
262 0, /*tp_doc*/
263 0, /*tp_traverse*/
264 0, /*tp_clear*/
265 0, /*tp_richcompare*/
266 0, /*tp_weaklistoffset*/
267 0, /*tp_iter*/
268 0, /*tp_iternext*/
269 RealTime_methods, /*tp_methods*/ //TypeObject Methods
270 0, /*tp_members*/
271 0, /*tp_getset*/
272 0, /*tp_base*/
273 0, /*tp_dict*/
274 0, /*tp_descr_get*/
275 0, /*tp_descr_set*/
276 0, /*tp_dictoffset*/
277 0, /*tp_init*/
278 0, /*tp_alloc*/
279 0, /*tp_new*/
280 0, /*tp_free*/
281 0, /*tp_is_gc*/
282 };
283
284
285 /* Remaining Functions Exposed by the MODULE */
286
287
288 /* New RealTime object from Frame (with given samplerate) */
289 /*static*/ PyObject *
290 RealTime_frame2RealTime(PyObject *ignored, PyObject *args)
291 {
292
293 long frame;
294 unsigned int sampleRate;
295
296 if (!PyArg_ParseTuple(args, "lI:realtime.fame2RealTime ",
297 &frame,
298 &sampleRate))
299 return NULL;
300 /*Doc:: 5.5 Parsing arguments and building values*/
301
302 RealTimeObject *self;
303 self = PyObject_New(RealTimeObject, &RealTime_Type);
304 if (self == NULL)
305 return NULL;
306
307 self->rt = new RealTime::RealTime(
308 RealTime::frame2RealTime(frame,sampleRate));
309
310 return (PyObject *) self;
311 }
312
313 /* New RealTime object from sec and nsec */
314 /*static*/ PyObject *
315 RealTime_new(PyObject *ignored, PyObject *args)
316 {
317
318 unsigned int sec = 0;
319 unsigned int nsec = 0;
320 double unary = 0;
321 const char *fmt = NULL;
322
323 /*Doc:: 5.5 Parsing arguments and building values*/
324 if (
325
326 !PyArg_ParseTuple(args, "|sd:realtime.new ",
327 (const char *) &fmt,
328 (double *) &unary) &&
329
330 !PyArg_ParseTuple(args, "|II:realtime.new ",
331 (unsigned int*) &sec,
332 (unsigned int*) &nsec)
333
334 ) {
335 PyErr_SetString(PyExc_TypeError,
336 "RealTime initialised with wrong arguments.");
337 return NULL; }
338
339 PyErr_Clear();
340
341 RealTimeObject *self =
342 PyObject_New(RealTimeObject, &RealTime_Type);
343 if (self == NULL) return NULL;
344
345 self->rt = NULL;
346
347 if (sec == 0 && nsec == 0 && fmt == 0)
348 self->rt = new RealTime::RealTime();
349 else if (fmt == 0)
350 self->rt = new RealTime::RealTime(sec,nsec);
351 else {
352
353 if (!string(fmt).compare("float") ||
354 !string(fmt).compare("seconds"))
355 self->rt = new RealTime::RealTime(
356 RealTime::fromSeconds((double) unary));
357
358 if (!string(fmt).compare("milliseconds")) {
359 self->rt = new RealTime::RealTime(
360 RealTime::fromSeconds((double) unary / 1000.0)); }
361 }
362
363 if (!self->rt) {
364 PyErr_SetString(PyExc_TypeError,
365 "RealTime initialised with wrong arguments.");
366 return NULL;
367 }
368
369 return (PyObject *) self;
370 }
371
372
373 /* pyRealTime Module's methods table */
374 static PyMethodDef Module_methods[] = {
375
376 {"frame2RealTime", (PyCFunction)RealTime_frame2RealTime, METH_VARARGS,
377 PyDoc_STR("frame2RealTime((int64)frame, (uint32)sampleRate ) -> returns new RealTime object from frame.")},
378
379 {"realtime", RealTime_new, METH_VARARGS,
380 PyDoc_STR("realtime() -> returns new RealTime object")},
381
382 {NULL, NULL} /* sentinel */
383 };
384
385
386 /* PyRealTime C API functions */
387
388
389
390 /*RealTime from PyRealTime*/
391 RealTime*
392 PyRealTime_AsPointer (PyObject *self) {
393
394 RealTimeObject *s = (RealTimeObject*) self;
395
396 if (!PyRealTime_Check(s)) {
397 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
398 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
399 return NULL; }
400 return s->rt; };
401
402 /*PyRealTime from RealTime*/
403 PyObject*
404 PyRealTime_FromRealTime(Vamp::RealTime *rt) {
405
406 RealTimeObject *self =
407 PyObject_New(RealTimeObject, &RealTime_Type);
408 if (self == NULL) return NULL;
409
410 self->rt = new RealTime::RealTime(*rt);
411 return (PyObject*) self;
412 }
413
414
415 /* Module initialization (includes extern "C" {...}) */
416 PyMODINIT_FUNC
417 initpyRealTime(void)
418 {
419 PyObject *m;
420
421 /* Finalize the type object including setting type of the new type
422 * object; doing it here is required for portability to Windows
423 * without requiring C++. */
424 if (PyType_Ready(&RealTime_Type) < 0)
425 return;
426
427 /* Create the module and add the functions */
428 m = Py_InitModule3("pyRealTime", Module_methods, module_doc);
429 if (m == NULL)
430 return;
431
432 // PyModule_AddObject(m, "realtime", (PyObject *)&RealTime_Type);
433
434 }