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