annotate host/pyRealTime.cpp @ 14:8cd6346e755f

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