annotate PyRealTime.cpp @ 92:a6718f9fe942

If a module appears to redefine one of our own types, refuse to load it. Also clear out the class dict for all refused modules now, so that we don't get stale names on the next scan due to not having cleared the module on unload
author Chris Cannam
date Mon, 14 Jan 2019 16:19:44 +0000
parents 62dcaa5fe6f8
children 2a9fb03458d7
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@58 208 /// TODO: implement all methods available in Vamp::RealTime() objects
fazekasgy@37 209
fazekasgy@37 210 static PyObject *
fazekasgy@37 211 RealTime_add(PyObject *s, PyObject *w)
fazekasgy@37 212 {
fazekasgy@37 213 RealTimeObject *result =
fazekasgy@37 214 PyObject_New(RealTimeObject, &RealTime_Type);
fazekasgy@37 215 if (result == NULL) return NULL;
fazekasgy@37 216
fazekasgy@37 217 result->rt = new RealTime(
fazekasgy@37 218 *((RealTimeObject*)s)->rt + *((RealTimeObject*)w)->rt);
fazekasgy@37 219 return (PyObject*)result;
fazekasgy@37 220 }
fazekasgy@37 221
fazekasgy@37 222 static PyObject *
fazekasgy@37 223 RealTime_subtract(PyObject *s, PyObject *w)
fazekasgy@37 224 {
fazekasgy@37 225 RealTimeObject *result =
fazekasgy@37 226 PyObject_New(RealTimeObject, &RealTime_Type);
fazekasgy@37 227 if (result == NULL) return NULL;
fazekasgy@37 228
fazekasgy@37 229 result->rt = new RealTime(
fazekasgy@37 230 *((RealTimeObject*)s)->rt - *((RealTimeObject*)w)->rt);
fazekasgy@37 231 return (PyObject*)result;
fazekasgy@37 232 }
fazekasgy@37 233
fazekasgy@37 234 static PyNumberMethods realtime_as_number =
fazekasgy@37 235 {
fazekasgy@37 236 RealTime_add, /*nb_add*/
fazekasgy@37 237 RealTime_subtract, /*nb_subtract*/
fazekasgy@37 238 0, /*nb_multiply*/
fazekasgy@37 239 0, /*nb_divide*/
fazekasgy@37 240 0, /*nb_remainder*/
fazekasgy@37 241 0, /*nb_divmod*/
fazekasgy@37 242 0, /*nb_power*/
fazekasgy@37 243 0, /*nb_neg*/
fazekasgy@37 244 0, /*nb_pos*/
fazekasgy@37 245 0, /*(unaryfunc)array_abs,*/
fazekasgy@37 246 0, /*nb_nonzero*/
fazekasgy@37 247 0, /*nb_invert*/
fazekasgy@37 248 0, /*nb_lshift*/
fazekasgy@37 249 0, /*nb_rshift*/
fazekasgy@37 250 0, /*nb_and*/
fazekasgy@37 251 0, /*nb_xor*/
fazekasgy@37 252 0, /*nb_or*/
fazekasgy@37 253 0, /*nb_coerce*/
fazekasgy@37 254 0, /*nb_int*/
fazekasgy@37 255 0, /*nb_long*/
fazekasgy@37 256 (unaryfunc)RealTime_float,/*nb_float*/
fazekasgy@37 257 0, /*nb_oct*/
fazekasgy@37 258 0, /*nb_hex*/
fazekasgy@37 259 };
fazekasgy@37 260
fazekasgy@37 261 /* REAL-TIME TYPE OBJECT */
fazekasgy@37 262
fazekasgy@37 263 #define RealTime_alloc PyType_GenericAlloc
fazekasgy@37 264 #define RealTime_free PyObject_Del
fazekasgy@37 265
fazekasgy@37 266 /* Doc:: 10.3 Type Objects */ /* static */
fazekasgy@37 267 PyTypeObject RealTime_Type =
fazekasgy@37 268 {
fazekasgy@37 269 PyObject_HEAD_INIT(NULL)
fazekasgy@37 270 0, /*ob_size*/
fazekasgy@37 271 "vampy.RealTime", /*tp_name*/
fazekasgy@37 272 sizeof(RealTimeObject), /*tp_basicsize*/
fazekasgy@37 273 0,//sizeof(RealTime), /*tp_itemsize*/
fazekasgy@37 274 /* methods */
fazekasgy@37 275 (destructor)RealTimeObject_dealloc, /*tp_dealloc*/
fazekasgy@37 276 0, /*tp_print*/
fazekasgy@37 277 (getattrfunc)RealTime_getattr, /*tp_getattr*/
fazekasgy@37 278 (setattrfunc)RealTime_setattr, /*tp_setattr*/
fazekasgy@37 279 0, /*tp_compare*/
fazekasgy@37 280 RealTime_repr, /*tp_repr*/
fazekasgy@37 281 &realtime_as_number, /*tp_as_number*/
fazekasgy@37 282 0, /*tp_as_sequence*/
fazekasgy@37 283 0, /*tp_as_mapping*/
fazekasgy@37 284 0, /*tp_hash*/
fazekasgy@37 285 0,//(ternaryfunc)RealTime_new, /*tp_call*/
fazekasgy@37 286 0, /*tp_str*/
fazekasgy@37 287 0, /*tp_getattro*/
fazekasgy@37 288 0, /*tp_setattro*/
fazekasgy@37 289 0, /*tp_as_buffer*/
fazekasgy@37 290 Py_TPFLAGS_DEFAULT, /*tp_flags*/
fazekasgy@37 291 "RealTime Object", /*tp_doc*/
fazekasgy@37 292 0, /*tp_traverse*/
fazekasgy@37 293 0, /*tp_clear*/
fazekasgy@37 294 0, /*tp_richcompare*/
fazekasgy@37 295 0, /*tp_weaklistoffset*/
fazekasgy@37 296 0, /*tp_iter*/
fazekasgy@37 297 0, /*tp_iternext*/
fazekasgy@37 298 RealTime_methods, /*tp_methods*/ //TypeObject Methods
fazekasgy@37 299 0, /*tp_members*/
fazekasgy@37 300 0, /*tp_getset*/
fazekasgy@37 301 0, /*tp_base*/
fazekasgy@37 302 0, /*tp_dict*/
fazekasgy@37 303 0, /*tp_descr_get*/
fazekasgy@37 304 0, /*tp_descr_set*/
fazekasgy@37 305 0, /*tp_dictoffset*/
fazekasgy@37 306 0, /*tp_init*/
fazekasgy@37 307 RealTime_alloc, /*tp_alloc*/
fazekasgy@37 308 RealTime_new, /*tp_new*/
fazekasgy@37 309 RealTime_free, /*tp_free*/
fazekasgy@37 310 0, /*tp_is_gc*/
fazekasgy@37 311 };
fazekasgy@37 312
fazekasgy@37 313
fazekasgy@37 314
fazekasgy@37 315 /* PyRealTime C++ API */
fazekasgy@37 316
fazekasgy@37 317 /*PyRealTime from RealTime pointer
fazekasgy@37 318 PyObject*
fazekasgy@37 319 PyRealTime_FromRealTime(Vamp::RealTime *rt) {
fazekasgy@37 320
fazekasgy@37 321 RealTimeObject *self =
fazekasgy@37 322 PyObject_New(RealTimeObject, &RealTime_Type);
fazekasgy@37 323 if (self == NULL) return NULL;
fazekasgy@37 324
fazekasgy@37 325 self->rt = new RealTime(*rt);
fazekasgy@37 326 return (PyObject*) self;
fazekasgy@37 327 }*/
fazekasgy@37 328
fazekasgy@37 329
fazekasgy@37 330 /*PyRealTime from RealTime*/
fazekasgy@37 331 PyObject*
fazekasgy@37 332 PyRealTime_FromRealTime(Vamp::RealTime& rt) {
fazekasgy@37 333
fazekasgy@37 334 RealTimeObject *self =
fazekasgy@37 335 PyObject_New(RealTimeObject, &RealTime_Type);
fazekasgy@37 336 if (self == NULL) return NULL;
fazekasgy@37 337
fazekasgy@37 338 self->rt = new RealTime(rt);
fazekasgy@37 339 return (PyObject*) self;
fazekasgy@37 340 }
fazekasgy@37 341
fazekasgy@37 342 /*RealTime* from PyRealTime*/
fazekasgy@37 343 const Vamp::RealTime*
fazekasgy@37 344 PyRealTime_AsRealTime (PyObject *self) {
fazekasgy@37 345
fazekasgy@37 346 RealTimeObject *s = (RealTimeObject*) self;
fazekasgy@37 347
fazekasgy@37 348 if (!PyRealTime_Check(s)) {
fazekasgy@37 349 PyErr_SetString(PyExc_TypeError, "RealTime Object Expected.");
fazekasgy@37 350 cerr << "in call PyRealTime_AsPointer(): RealTime Object Expected. " << endl;
fazekasgy@37 351 return NULL; }
fazekasgy@37 352 return s->rt;
fazekasgy@37 353 };
fazekasgy@37 354