annotate PyRealTime.cpp @ 53:7e59caea821b

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