comparison native/PyRealTime.cpp @ 52:b56513f872a5

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